diff --git a/doc/build/html/_modules/index.html b/doc/build/html/_modules/index.html index 0139a40..84f99a9 100644 --- a/doc/build/html/_modules/index.html +++ b/doc/build/html/_modules/index.html @@ -6,7 +6,7 @@
-
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 kollacli.i18n as u
from kollacli.api.exceptions import InvalidArgument
@@ -74,6 +74,7 @@
[docs] def async_deploy(self, hostnames=[],
serial_flag=False, verbose_level=1):
+ # type: (List[str], bool, int) -> Job
"""Deploy.
Deploy containers to hosts.
@@ -87,10 +88,10 @@
:return: Job object
:rtype: Job
"""
- check_arg(hostnames, u._('Host names'), list,
+ check_arg(hostnames, u._('Host names'), list,
empty_ok=True, none_ok=True)
- check_arg(serial_flag, u._('Serial flag'), bool)
- check_arg(verbose_level, u._('Verbose level'), int)
+ check_arg(serial_flag, u._('Serial flag'), bool)
+ check_arg(verbose_level, u._('Verbose level'), int)
hostnames = safe_decode(hostnames)
ansible_job = actions.deploy(hostnames,
@@ -98,6 +99,7 @@
return Job(ansible_job)
[docs] def async_upgrade(self, verbose_level=1):
+ # type: (int) -> Job
"""Upgrade.
:param verbose_level: the higher the number, the more verbose
@@ -108,12 +110,13 @@
Upgrade containers to new version specified by the property
"openstack_release."
"""
- check_arg(verbose_level, u._('Verbose level'), int)
+ check_arg(verbose_level, u._('Verbose level'), int)
ansible_job = actions.upgrade(verbose_level)
return Job(ansible_job)
[docs] def async_host_destroy(self, hostnames, destroy_type, verbose_level=1,
include_data=False):
+ # type: (List[str], str, int, bool) -> Job
"""Destroy Hosts.
Stops and removes all kolla related docker containers on the
@@ -131,14 +134,14 @@
:rtype: Job
"""
- check_arg(hostnames, u._('Host names'), list)
- check_arg(destroy_type, u._('Destroy type'), str)
- check_arg(verbose_level, u._('Verbose level'), int)
- check_arg(include_data, u._('Include data'), bool)
- if destroy_type not in ['stop', 'kill']:
+ check_arg(hostnames, u._('Host names'), list)
+ check_arg(destroy_type, u._('Destroy type'), str)
+ check_arg(verbose_level, u._('Verbose level'), int)
+ check_arg(include_data, u._('Include data'), bool)
+ if destroy_type not in ['stop', 'kill']:
raise InvalidArgument(
- u._('Invalid destroy type ({type}). Must be either '
- '"stop" or "kill".').format(type=destroy_type))
+ u._('Invalid destroy type ({type}). Must be either '
+ '"stop" or "kill".').format(type=destroy_type))
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
@@ -149,6 +152,7 @@
return Job(ansible_job)
[docs] def async_host_precheck(self, hostnames, verbose_level=1):
+ # type: (List[str], int) -> Job
"""Check pre-deployment configuration of hosts.
Check if host is ready for a new deployment. This will fail if
@@ -161,8 +165,8 @@
:return: Job object
:rtype: Job
"""
- check_arg(hostnames, u._('Host names'), list)
- check_arg(verbose_level, u._('Verbose level'), int)
+ check_arg(hostnames, u._('Host names'), list)
+ check_arg(verbose_level, u._('Verbose level'), int)
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.validate_hostnames(hostnames)
@@ -202,7 +206,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/api/client.html b/doc/build/html/_modules/kollacli/api/client.html
index 3d5b54f..8e1b349 100644
--- a/doc/build/html/_modules/kollacli/api/client.html
+++ b/doc/build/html/_modules/kollacli/api/client.html
@@ -6,7 +6,7 @@
- kollacli.api.client — kollacli 3.0.1.dev435 documentation
+ kollacli.api.client — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 kollacli.i18n as u
import logging
@@ -78,12 +78,12 @@
from kollacli.api.support import SupportApi
from kollacli.common.utils import get_log_level
-CONSOLE_MESSAGE_FORMAT = '%(message)s'
+CONSOLE_MESSAGE_FORMAT = '%(message)s'
LOG_FILE_MESSAGE_FORMAT = \
- '[%(asctime)s] %(levelname)-8s %(name)s %(message)s'
+ '[%(asctime)s] %(levelname)-8s %(name)s %(message)s'
LOG = None
-VERSION = '1.0'
+VERSION = '1.0'
[docs]class ClientApi(
@@ -96,8 +96,7 @@
ServiceApi,
SupportApi,
):
- """
- Client API Notes
+ """Client API Notes
Objects returned by the API contain a local copy of the information
in the datastore. While changes made to the local copy will be
@@ -111,19 +110,21 @@
self._configure_logging()
[docs] def enable_console_logging(self, level, enable=True):
+ # type: (int, bool) -> None
"""enable/disable console logging for the api
enable: True/False
level: logging.INFO, logging.DEBUG, logging.WARNING,
logging.CRITICAL...
"""
- root_logger = logging.getLogger('')
+ root_logger = logging.getLogger('')
console = logging.StreamHandler(sys.stderr)
if enable:
console.setLevel(level)
@@ -135,7 +136,7 @@
def _configure_logging(self):
global LOG
- root_logger = logging.getLogger('')
+ root_logger = logging.getLogger('')
root_logger.setLevel(logging.DEBUG)
handler_found = False
@@ -145,19 +146,19 @@
handler_found = True
break
if not handler_found:
- # logger has not been set up
+ # logger has not been set up
try:
rotate_handler = RotatingFileHandler(
os.path.join(os.path.abspath(os.sep),
- 'var', 'log', 'kolla', 'kolla.log'),
+ 'var', 'log', 'kolla', 'kolla.log'),
maxBytes=self._get_kolla_log_file_size(),
backupCount=4)
except IOError as e:
- # most likely the caller is not part of the kolla group
- raise IOError(u._('Permission denied to run the kolla client.'
- '\nPlease add user to the kolla group and '
- 'then log out and back in. {error}')
+ # most likely the caller is not part of the kolla group
+ raise IOError(u._('Permission denied to run the kolla client.'
+ '\nPlease add user to the kolla group and '
+ 'then log out and back in. {error}')
.format(error=str(e)))
formatter = logging.Formatter(LOG_FILE_MESSAGE_FORMAT)
@@ -167,8 +168,9 @@
LOG = logging.getLogger(__name__)
def _get_kolla_log_file_size(self):
- envvar = 'KOLLA_LOG_FILE_SIZE'
- size_str = os.environ.get(envvar, '500000')
+ # type: () -> int
+ envvar = 'KOLLA_LOG_FILE_SIZE'
+ size_str = os.environ.get(envvar, '500000')
try:
size = int(size_str)
except Exception:
@@ -207,7 +209,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/api/deploy.html b/doc/build/html/_modules/kollacli/api/deploy.html
index b11c75c..06b11e1 100644
--- a/doc/build/html/_modules/kollacli/api/deploy.html
+++ b/doc/build/html/_modules/kollacli/api/deploy.html
@@ -6,7 +6,7 @@
- kollacli.api.deploy — kollacli 3.0.1.dev435 documentation
+ kollacli.api.deploy — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import kollacli.i18n as u
@@ -73,6 +73,7 @@
[docs]class DeployApi(object):
[docs] def deploy_set_mode(self, remote_mode):
+ # type: (bool) -> None
"""Set deploy mode.
Set deploy mode to either local or remote. Local indicates
@@ -85,7 +86,7 @@
:param remote_mode: if remote mode is True deployment is done via ssh
:type remote_mode: bool
"""
- check_arg(remote_mode, u._('Remote mode'), bool)
+ check_arg(remote_mode, u._('Remote mode'), bool)
inventory = Inventory.load()
inventory.set_deploy_mode(remote_mode)
Inventory.save(inventory)
@@ -122,7 +123,7 @@
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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.
"""Exception definitions."""
import kollacli.i18n as u
@@ -68,7 +68,7 @@
"""KollaClient Base Class Exception"""
def __init__(self, message, *args):
if not message:
- message = u._('An unknown exception occurred.')
+ message = u._('An unknown exception occurred.')
super(ClientException, self).__init__(message, *args)
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy import copy
import kollacli.i18n as u
@@ -70,123 +70,15 @@
[docs]class GroupApi(object):
-[docs] class Group(object):
- def __init__(self, groupname, servicenames, hostnames):
- self.name = groupname
- self._servicenames = servicenames
- self._hostnames = hostnames
-
-[docs] def get_name(self):
- """Get name
-
- :return: group name
- :rtype: string
- """
- return self.name
-
-[docs] def get_services(self):
- """Get names of services associated with this group.
-
- :return: service names
- :rtype: list of strings
- """
- return copy(self._servicenames)
-
-[docs] def add_service(self, servicename):
- """Add service to group
-
- :param servicename: name of the service to add to the group
- :type servicename: string
- """
- check_arg(servicename, u._('Service name'), str)
- servicename = safe_decode(servicename)
- inventory = Inventory.load()
- inventory.validate_servicenames([servicename])
-
- group_services = inventory.get_group_services()
- self._servicenames = group_services[self.name]
- if servicename not in self._servicenames:
- # service not associated with group, add it
- inventory.add_group_to_service(self.name, servicename)
- self._servicenames.append(servicename)
- Inventory.save(inventory)
-
-[docs] def remove_service(self, servicename):
- """Remove service from group
-
- :param servicename: name of the service to remove from the group
- :type servicename: string
-
- """
- check_arg(servicename, u._('Service name'), str)
- servicename = safe_decode(servicename)
- inventory = Inventory.load()
- inventory.validate_servicenames([servicename])
-
- group_services = inventory.get_group_services()
- self._servicenames = group_services[self.name]
- if servicename in self._servicenames:
- # service is associated with group, remove it
- inventory.remove_group_from_service(self.name, servicename)
- self._servicenames.remove(servicename)
- Inventory.save(inventory)
-
-[docs] def get_hosts(self):
- """Get names of hosts associated with this group.
-
- :return: host names
- :rtype: list of strings
- """
- return copy(self._hostnames)
-
-[docs] def add_host(self, hostname):
- """Add host to group
-
- :param hostname: name of the host to add to the group
- :type hostname: string
-
- """
- check_arg(hostname, u._('Host name'), str)
- hostname = safe_decode(hostname)
- inventory = Inventory.load()
- inventory.validate_hostnames([hostname])
-
- group = inventory.get_group(self.name)
- self._hostnames = group.get_hostnames()
- if hostname not in self._hostnames:
- # host not associated with group, add it
- inventory.add_host(hostname, self.name)
- self._hostnames.append(hostname)
- Inventory.save(inventory)
-
-[docs] def remove_host(self, hostname):
- """Remove host from group
-
- :param hostname: name of the host to remove from the group
- :type hostname: string
-
- """
- check_arg(hostname, u._('Host name'), str)
- hostname = safe_decode(hostname)
- inventory = Inventory.load()
- inventory.validate_hostnames([hostname])
-
- group = inventory.get_group(self.name)
- self._hostnames = group.get_hostnames()
- if hostname in self._hostnames:
- # host is associated with group, remove it
- inventory.remove_host(hostname, self.name)
- self._hostnames.remove(hostname)
- Inventory.save(inventory)
-
[docs] def group_add(self, groupnames):
+ # type: (List[str]) -> None
"""Add groups to the inventory
:param groupnames: names of the groups to add to the inventory
:type groupnames: list of strings
"""
- check_arg(groupnames, u._('Group names'), list)
+ check_arg(groupnames, u._('Group names'), list)
groupnames = safe_decode(groupnames)
inventory = Inventory.load()
@@ -195,12 +87,13 @@
Inventory.save(inventory)
[docs] def group_remove(self, groupnames):
+ # type: (List[str]) -> None
"""Remove groups from the inventory
:param groupnames: names of the groups to remove from the inventory
:type groupnames: list of strings
"""
- check_arg(groupnames, u._('Group names'), list)
+ check_arg(groupnames, u._('Group names'), list)
groupnames = safe_decode(groupnames)
inventory = Inventory.load()
@@ -209,6 +102,7 @@
Inventory.save(inventory)
[docs] def group_get_all(self):
+ # type: () -> List[Group]
"""Get all groups in the inventory
:return: groups
@@ -217,6 +111,7 @@
return self._get_groups(None, get_all=True)
[docs] def group_get(self, groupnames):
+ # type: (List[str]) -> List[Group]
"""Get selected groups in the inventory
:param groupnames: names of groups to be read
@@ -224,11 +119,12 @@
:return: groups
:rtype: list of Group objects
"""
- check_arg(groupnames, u._('Group names'), list)
+ check_arg(groupnames, u._('Group names'), list)
groupnames = safe_decode(groupnames)
return self._get_groups(groupnames)
def _get_groups(self, groupnames, get_all=False):
+ # type: (List[str], bool) -> List[Group]
groups = []
inventory = Inventory.load()
if get_all:
@@ -239,11 +135,129 @@
group_services = inventory.get_group_services()
for groupname in groupnames:
inv_group = inventory.get_group(groupname)
- group = self.Group(groupname,
- group_services[groupname],
- inv_group.get_hostnames())
+ group = Group(groupname,
+ group_services[groupname],
+ inv_group.get_hostnames())
groups.append(group)
- return groups
+ return groups
+
+
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy import copy
import kollacli.i18n as u
@@ -70,38 +70,13 @@
[docs]class HostApi(object):
-[docs] class Host(object):
- """Host"""
- def __init__(self, hostname, groupnames):
- self.name = hostname
- self._groupnames = groupnames
-
-[docs] def get_name(self):
- """Get name
-
- :return: host name
- :rtype: string
- """
- return self.name
-
-[docs] def get_groups(self):
- """Get names of the groups associated with this host
-
- :return: group names
- :rtype: list of strings
-
- Note: If the groups associated with this host change after this
- host is fetched, the host must be re-fetched to reflect those
- changes.
- """
- return copy(self._groupnames)
-
[docs] def host_add(self, hostnames):
+ # type: (List[str]) -> None
"""Add hosts to the inventory
:param hostnames: list of strings
"""
- check_arg(hostnames, u._('Host names'), list)
+ check_arg(hostnames, u._('Host names'), list)
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
@@ -114,11 +89,12 @@
Inventory.save(inventory)
[docs] def host_remove(self, hostnames):
+ # type: (List[str]) -> None
"""Remove hosts from the inventory
:param hostnames: list of strings
"""
- check_arg(hostnames, u._('Host names'), list)
+ check_arg(hostnames, u._('Host names'), list)
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
@@ -131,26 +107,28 @@
Inventory.save(inventory)
[docs] def host_get_all(self):
+ # type: () -> List[Host]
"""Get all hosts in the inventory
:return: Hosts
- :rtype: Host
+ :rtype: list of Host objects
"""
inventory = Inventory.load()
hosts = []
host_groups = inventory.get_host_groups()
for hostname, groupnames in host_groups.items():
- hosts.append(self.Host(hostname, groupnames))
+ hosts.append(Host(hostname, groupnames))
return hosts
[docs] def host_get(self, hostnames):
+ # type: (List[str]) -> List[Host]
"""Get selected hosts in the inventory
:param hostnames: list of strings
:return: hosts
- :rtype: Host
+ :rtype: list of Host objects
"""
- check_arg(hostnames, u._('Host names'), list)
+ check_arg(hostnames, u._('Host names'), list)
hostnames = safe_decode(hostnames)
inventory = Inventory.load()
inventory.validate_hostnames(hostnames)
@@ -158,10 +136,11 @@
hosts = []
host_groups = inventory.get_host_groups()
for hostname in hostnames:
- hosts.append(self.Host(hostname, host_groups[hostname]))
+ hosts.append(Host(hostname, host_groups[hostname]))
return hosts
[docs] def host_ssh_check(self, hostnames):
+ # type: (List[str]) -> Dict[str,Dict[str,object]]
"""Check hosts for ssh connectivity
Check status is a dictionary of form:
@@ -175,7 +154,7 @@
:return: check status
:rtype: dictionary
"""
- check_arg(hostnames, u._('Host names'), list)
+ check_arg(hostnames, u._('Host names'), list)
inventory = Inventory.load()
hostnames = safe_decode(hostnames)
inventory.validate_hostnames(hostnames)
@@ -183,6 +162,7 @@
return summary
[docs] def host_setup(self, hosts_info):
+ # type: (Dict[str,Dict[str,object]]) -> None
"""Setup multiple hosts for ssh access
hosts_info is a dictionary of form:
@@ -196,10 +176,41 @@
:param hosts_info: dictionary
"""
- check_arg(hosts_info, u._('Hosts info'), dict)
+ check_arg(hosts_info, u._('Hosts info'), dict)
inventory = Inventory.load()
inventory.validate_hostnames(hosts_info.keys())
- inventory.setup_hosts(hosts_info)
+ inventory.setup_hosts(hosts_info)
+
+
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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.
[docs]class Job(object):
@@ -68,6 +68,7 @@
self._ansible_job = ansible_job
[docs] def wait(self):
+ # type: () -> int
"""Wait for job to complete
:return: 0 if job succeeded, 1 if job failed
@@ -76,6 +77,7 @@
return self._ansible_job.wait()
[docs] def get_status(self):
+ # type: () -> int
"""Get status of job
:return: None: job is still running
@@ -87,6 +89,7 @@
return self._ansible_job.get_status()
[docs] def get_error_message(self):
+ # type: () -> str
"""Get error message
:return: if job failed, this will return the error message.
@@ -95,6 +98,7 @@
return self._ansible_job.get_error_message()
[docs] def get_console_output(self):
+ # type: () -> str
"""Get the console output from the job
:return: console output useful for debugging failed jobs.
@@ -138,7 +142,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/api/password.html b/doc/build/html/_modules/kollacli/api/password.html
index 2e3321d..8294a04 100644
--- a/doc/build/html/_modules/kollacli/api/password.html
+++ b/doc/build/html/_modules/kollacli/api/password.html
@@ -6,7 +6,7 @@
- kollacli.api.password — kollacli 3.0.1.dev435 documentation
+ kollacli.api.password — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,30 +47,33 @@
Source code for kollacli.api.password
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 kollacli.i18n as u
from kollacli.common.passwords import clear_password
from kollacli.common.passwords import get_password_names
+from kollacli.common.passwords import init_passwords
from kollacli.common.passwords import set_password
+from kollacli.common.passwords import set_password_sshkey
from kollacli.common.utils import check_arg
[docs]class PasswordApi(object):
[docs] def password_set(self, name, value):
+ # type: (str, str) -> None
"""Set password
:param name: name of the password
@@ -78,25 +81,53 @@
:param value: value of the password
:type value: string
"""
- check_arg(name, u._('Password name'), str)
+ check_arg(name, u._('Password name'), str)
+ check_arg(value, u._('Password value'), str, display_param=False)
set_password(name, value)
+[docs] def password_set_sshkey(self, name, private_key, public_key):
+ # type: (str, str, str) -> None
+ """Set password to an ssh key
+
+ :param name: name of the password
+ :type name: string
+ :param private_key: ssh private key
+ :type value: string
+ :param public_key: ssh public key
+ :type value: string
+ """
+ check_arg(name, u._('Password name'), str)
+ check_arg(private_key, u._('Private key'), str, display_param=False)
+ check_arg(public_key, u._('Public key'), str, display_param=False)
+ set_password_sshkey(name, private_key, public_key)
+
[docs] def password_clear(self, name):
+ # type: (str) -> None
"""Clear password
:param name: name of the password
:type name: string
"""
- check_arg(name, u._('Password name'), str)
+ check_arg(name, u._('Password name'), str)
clear_password(name)
[docs] def password_get_names(self):
+ # type: () -> List[str]
"""Get password names
:return: password names
:rtype: list of strings
"""
- return get_password_names()
+ return get_password_names()
+
+[docs] def password_init(self):
+ # type: () -> None
+ """Init empty passwords
+
+ Init empty passwords and ssh keys in /etc/kolla/passwords.yml
+ to auto-generated values
+ """
+ return init_passwords()
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import kollacli.i18n as u
@@ -71,49 +71,17 @@
LOG = logging.getLogger(__name__)
-GLOBAL_TYPE = 'global'
-GROUP_TYPE = 'group'
-HOST_TYPE = 'host'
+GLOBAL_TYPE = 'global'
+GROUP_TYPE = 'group'
+HOST_TYPE = 'host'
PROP_TYPES = [GLOBAL_TYPE, GROUP_TYPE, HOST_TYPE]
[docs]class PropertyApi(object):
-[docs] class Property(object):
- """Property
-
- Members:
- - name (str): key
- - value (str): value
- - file_name (str): name of file property is from
- - overrides (bool): does the property override some other value
- - orig_value (str): the value which is overridden or None
- - target (str): group or host name for group or host properties
- - prop_type (str): one of 'global', 'group' or 'host'
- - ovr_global (bool): true if property is overridden at global level
- - ovr_group (bool): true if property is overridden at group level
- - ovr_host (bool): true if property is overridden at host level
- """
- def __init__(self, ansible_property, override_flags):
- self.name = ansible_property.name
- self.value = ansible_property.value
- self.file_name = ansible_property.file_name
- self.overrides = ansible_property.overrides
- self.orig_value = ansible_property.orig_value
- self.target = ansible_property.target
- self.prop_type = ansible_property.prop_type
-
- if override_flags is not None:
- self.ovr_global = override_flags.ovr_global
- self.ovr_group = override_flags.ovr_group
- self.ovr_host = override_flags.ovr_host
- else:
- self.ovr_global = False
- self.ovr_group = False
- self.ovr_host = False
-
[docs] def property_set(self, property_dict,
property_type=GLOBAL_TYPE, change_set=None):
+ # type: (Dict[str,str], str, List[str]) -> None
"""Set a property
:param property_dict: property dictionary containing key / values
@@ -126,13 +94,16 @@
"""
for key, value in property_dict.items():
- check_arg(key, u._('Property Key'), str)
- check_arg(value, u._('Property Value'), str)
+ check_arg(key, u._('Property Key'), str)
+ check_arg(value, u._('Property Value'), str, empty_ok=True)
+ if '"' in value:
+ raise InvalidArgument(u._('Cannot use double quotes in '
+ 'a property value.'))
property_dict = safe_decode(property_dict)
self._check_type(property_type)
if property_type is not GLOBAL_TYPE:
- check_arg(change_set, u._('Change Set'), list, none_ok=True)
+ check_arg(change_set, u._('Change Set'), list, none_ok=True)
change_set = safe_decode(change_set)
ansible_properties = AnsibleProperties()
@@ -146,6 +117,7 @@
[docs] def property_clear(self, property_list, property_type=GLOBAL_TYPE,
change_set=None):
+ # type: (List[str], str, List[str]) -> None
"""Clear a property
:param property_list: property list
@@ -157,12 +129,12 @@
:type change_set: list of strings
"""
- check_arg(property_list, u._('Property List'), list)
+ check_arg(property_list, u._('Property List'), list)
property_list = safe_decode(property_list)
self._check_type(property_type)
if property_type is not GLOBAL_TYPE:
- check_arg(change_set, u._('Change Set'), list, none_ok=True)
+ check_arg(change_set, u._('Change Set'), list, none_ok=True)
change_set = safe_decode(change_set)
ansible_properties = AnsibleProperties()
@@ -175,6 +147,7 @@
ansible_properties.clear_host_property(property_list, change_set)
[docs] def property_get(self, property_type=GLOBAL_TYPE, get_set=None):
+ # type: (str, List[str]) -> List[Property]
"""Returns a list of Property objects
:param property_type: one of 'global', 'group', or 'host'
@@ -190,7 +163,6 @@
ansible_properties = AnsibleProperties()
- property_list = []
result_list = []
if property_type == GLOBAL_TYPE:
property_list = ansible_properties.get_all_unique()
@@ -202,16 +174,51 @@
override_flags = ansible_properties.get_all_override_flags()
for prop in property_list:
- result = self.Property(prop, override_flags.get(prop.name, None))
+ result = Property(prop, override_flags.get(prop.name, None))
result_list.append(result)
return result_list
def _check_type(self, property_type):
if property_type is None or property_type not in PROP_TYPES:
- raise InvalidArgument(u._('Property Type ({value} is not one of '
- 'global, group or host')
- .format(value=property_type))
+ raise InvalidArgument(u._('Property Type ({value} is not one of '
+ 'global, group or host')
+ .format(value=property_type))
+
+
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy import copy
import kollacli.i18n as u
@@ -70,68 +70,8 @@
[docs]class ServiceApi(object):
-[docs] class Service(object):
- """Service
-
- A service is one of the services available in openstack-kolla.
-
- For example, this would be how the murano services would be
- represented:
-
- - murano
- - parentname: None
- - childnames: [murano-api, murano-engine]
- - murano-api
- - parentname: murano
- - childnames: []
- - murano-engine
- - parentname: murano
- - childnames: []
- """
- def __init__(self, servicename, parentname=None,
- childnames=[], groupnames=[]):
- self.name = servicename
- self.parentname = parentname
- self._childnames = childnames
- self._groupnames = groupnames
-
-[docs] def get_name(self):
- """Get name
-
- :return: service name
- :rtype: string
- """
- return self.name
-
-[docs] def get_parent(self):
- """Get name of parent service
-
- :return: parent service name
- :rtype: string
- """
- return self.parentname
-
-[docs] def get_children(self):
- """Get names of the child services associated with this service
-
- :return: child names
- :rtype: list of strings
- """
- return copy(self._childnames)
-
-[docs] def get_groups(self):
- """Get names of the groups associated with this service
-
- :return: group names
- :rtype: list of strings
-
- Note: If the groups associated with this service change after this
- service is fetched, the service must be re-fetched to reflect those
- changes.
- """
- return copy(self._groupnames)
-
[docs] def service_get_all(self):
+ # type: () -> List[Service]
"""Get all services in the inventory
:return: services
@@ -140,6 +80,7 @@
return self._get_services(None, get_all=True)
[docs] def service_get(self, servicenames):
+ # type: (List[str]) -> List[Service]
"""Get selected services in the inventory
:param servicenames: names of services to be read
@@ -147,11 +88,12 @@
:return: services
:rtype: list of Service objects
"""
- check_arg(servicenames, u._('Service names'), list)
+ check_arg(servicenames, u._('Service names'), list)
servicenames = safe_decode(servicenames)
return self._get_services(servicenames)
def _get_services(self, servicenames, get_all=False):
+ # type: (List[str], bool) -> List[Service]
services = []
inventory = Inventory.load()
@@ -167,18 +109,86 @@
for servicename in servicenames:
inv_service = inventory.get_service(servicename)
if inv_service:
- service = self.Service(inv_service.name,
- None,
- inv_service.get_sub_servicenames(),
- inv_service.get_groupnames())
+ service = Service(inv_service.name,
+ None,
+ inv_service.get_sub_servicenames(),
+ inv_service.get_groupnames())
else:
inv_subservice = inventory.get_sub_service(servicename)
- service = self.Service(inv_subservice.name,
- inv_subservice.get_parent_servicename(),
- [],
- inv_subservice.get_groupnames())
+ service = Service(inv_subservice.name,
+ inv_subservice.get_parent_servicename(),
+ [],
+ inv_subservice.get_groupnames())
services.append(service)
- return services
+ return services
+
+
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 kollacli.i18n as u
import os
@@ -74,6 +74,7 @@
[docs]class SupportApi(object):
[docs] def support_dump(self, dirpath):
+ # type: (str) -> str
"""Dumps configuration data for debugging.
Dumps most files in /etc/kolla and /usr/share/kolla into a
@@ -85,15 +86,16 @@
:return: path to dump file
:rtype: string
"""
- check_arg(dirpath, u._('Directory path'), str)
+ check_arg(dirpath, u._('Directory path'), str)
dirpath = safe_decode(dirpath)
if not os.path.exists(dirpath):
- raise InvalidArgument(u._('Directory path: {path} does not exist')
+ raise InvalidArgument(u._('Directory path: {path} does not exist')
.format(path=dirpath))
dumpfile_path = dump(dirpath)
return dumpfile_path
[docs] def support_get_logs(self, servicenames, hostname, dirpath):
+ # type: (List[str], str, str) -> None
"""get container logs
Fetch the container log files of services from the specified hosts.
@@ -108,15 +110,15 @@
:param dirpath: path of directory where log files will be written
:type dirpath: string
"""
- check_arg(dirpath, u._('Directory path'), str)
+ check_arg(dirpath, u._('Directory path'), str)
dirpath = safe_decode(dirpath)
if not os.path.exists(dirpath):
- raise InvalidArgument(u._('Directory path: {path} does not exist')
+ raise InvalidArgument(u._('Directory path: {path} does not exist')
.format(path=dirpath))
- check_arg(servicenames, u._('Service names'), list)
+ check_arg(servicenames, u._('Service names'), list)
servicenames = safe_decode(servicenames)
- check_arg(hostname, u._('Host names'), str)
+ check_arg(hostname, u._('Host names'), str)
hostname = safe_decode(hostname)
get_logs(servicenames, hostname, dirpath)
@@ -153,7 +155,7 @@
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import time
import traceback
@@ -79,14 +79,14 @@
"""Deploy."""
[docs] def get_parser(self, prog_name):
parser = super(Deploy, self).get_parser(prog_name)
- parser.add_argument('--hosts', nargs='?',
- metavar='<host_list>',
- help=u._('Deployment host list'))
- parser.add_argument('--serial', action='store_true',
- help=u._('Deploy serially'))
- parser.add_argument('--timeout', nargs=1,
- metavar='<timeout>',
- help=u._('timeout (in minutes)'))
+ parser.add_argument('--hosts', nargs='?',
+ metavar='<host_list>',
+ help=u._('Deployment host list'))
+ parser.add_argument('--serial', action='store_true',
+ help=u._('Deploy serially'))
+ parser.add_argument('--timeout', nargs=1,
+ metavar='<timeout>',
+ help=u._('timeout (in minutes)'))
return parser
[docs] def take_action(self, parsed_args):
@@ -97,42 +97,42 @@
try:
if parsed_args.hosts:
host_list = parsed_args.hosts.strip()
- hosts = host_list.split(',')
+ hosts = host_list.split(',')
if parsed_args.serial:
serial_flag = True
if parsed_args.timeout:
try:
timeout = float(parsed_args.timeout[0])
except Exception:
- raise CommandError(u._('Timeout value is not a number.'))
+ raise CommandError(u._('Timeout value is not a number.'))
timeout_target = time.time() + (60 * timeout)
job = CLIENT.async_deploy(hosts, serial_flag,
verbose_level)
- # wait for job to complete
+ # wait for job to complete
status = None
while status is None:
if timeout_target and time.time() > timeout_target:
job.kill()
- raise CommandError(u._('Job timed out and was killed.'))
+ raise CommandError(u._('Job timed out and was killed.'))
time.sleep(1)
status = job.get_status()
- # job is done
+ # job is done
if verbose_level > 2:
- LOG.info('\n\n' + 80 * '=')
- LOG.info(u._('DEBUG command output:\n{out}')
+ LOG.info('\n\n' + 80 * '=')
+ LOG.info(u._('DEBUG command output:\n{out}')
.format(out=job.get_console_output()))
if status == 0:
if verbose_level > 1:
- # log any ansible warnings
+ # log any ansible warnings
msg = job.get_error_message()
if msg:
LOG.warn(msg)
- LOG.info(u._('Success'))
+ LOG.info(u._('Success'))
else:
- raise CommandError(u._('Job failed:\n{msg}')
+ raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
except Exception:
@@ -148,23 +148,23 @@
"""
[docs] def get_parser(self, prog_name):
parser = super(Setdeploy, self).get_parser(prog_name)
- parser.add_argument('mode', metavar='<mode>',
- help=u._('mode=<local, remote>'))
+ parser.add_argument('mode', metavar='<mode>',
+ help=u._('mode=<local, remote>'))
return parser
[docs] def take_action(self, parsed_args):
try:
mode = parsed_args.mode.strip()
remote_flag = True
- if mode == 'local':
+ if mode == 'local':
remote_flag = False
- LOG.info(u._('Please note that local mode is not supported '
- 'and should never be used in production '
- 'environments.'))
- elif mode != 'remote':
+ LOG.info(u._('Please note that local mode is not supported '
+ 'and should never be used in production '
+ 'environments.'))
+ elif mode != 'remote':
raise CommandError(
- u._('Invalid deploy mode. Mode must be '
- 'either "local" or "remote".'))
+ u._('Invalid deploy mode. Mode must be '
+ 'either "local" or "remote".'))
CLIENT.deploy_set_mode(remote_flag)
except CommandError as e:
raise e
@@ -203,7 +203,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/exceptions.html b/doc/build/html/_modules/kollacli/commands/exceptions.html
index 75d4d06..97bbf84 100644
--- a/doc/build/html/_modules/kollacli/commands/exceptions.html
+++ b/doc/build/html/_modules/kollacli/commands/exceptions.html
@@ -6,7 +6,7 @@
- kollacli.commands.exceptions — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.exceptions — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.exceptions
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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.
"""Exception definitions."""
import kollacli.i18n as u
@@ -67,7 +67,7 @@
[docs]class CommandError(Exception):
"""CLI command error"""
def __init__(self, message, *args):
- prefix = u._('ERROR: ')
+ prefix = u._('ERROR: ')
if not message.startswith(prefix):
message = prefix + message
super(CommandError, self).__init__(message, *args)
@@ -104,7 +104,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/group.html b/doc/build/html/_modules/kollacli/commands/group.html
index 84d74fc..d2902b5 100644
--- a/doc/build/html/_modules/kollacli/commands/group.html
+++ b/doc/build/html/_modules/kollacli/commands/group.html
@@ -6,7 +6,7 @@
- kollacli.commands.group — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.group — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.group
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 traceback
import kollacli.i18n as u
@@ -67,6 +67,8 @@
from kollacli.api.client import ClientApi
from kollacli.api.exceptions import ClientException
from kollacli.commands.exceptions import CommandError
+from kollacli.common.utils import convert_lists_to_string
+
from cliff.command import Command
from cliff.lister import Lister
@@ -78,8 +80,8 @@
"""Add group to openstack-kolla."""
[docs] def get_parser(self, prog_name):
parser = super(GroupAdd, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -98,8 +100,8 @@
[docs] def get_parser(self, prog_name):
parser = super(GroupRemove, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -117,10 +119,10 @@
"""Add host to group."""
[docs] def get_parser(self, prog_name):
parser = super(GroupAddhost, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
- parser.add_argument('hostname', metavar='<hostname>',
- help=u._('Host name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
+ parser.add_argument('hostname', metavar='<hostname>',
+ help=u._('Host name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -142,10 +144,10 @@
[docs] def get_parser(self, prog_name):
parser = super(GroupRemovehost, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
- parser.add_argument('hostname', metavar='<hostname>',
- help=u._('Host name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
+ parser.add_argument('hostname', metavar='<hostname>',
+ help=u._('Host name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -167,14 +169,15 @@
[docs] def take_action(self, parsed_args):
try:
- data = [('', '')]
+ data = [('', '')]
groups = CLIENT.group_get_all()
if groups:
data = []
for group in groups:
data.append((group.get_name(),
sorted(group.get_hosts())))
- return ((u._('Group'), u._('Hosts')), sorted(data))
+ data = convert_lists_to_string(data, parsed_args)
+ return ((u._('Group'), u._('Hosts')), sorted(data))
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
@@ -185,10 +188,10 @@
"""Add service to group."""
[docs] def get_parser(self, prog_name):
parser = super(GroupAddservice, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
- parser.add_argument('servicename', metavar='<servicename>',
- help=u._('Service name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
+ parser.add_argument('servicename', metavar='<servicename>',
+ help=u._('Service name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -210,10 +213,10 @@
[docs] def get_parser(self, prog_name):
parser = super(GroupRemoveservice, self).get_parser(prog_name)
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
- parser.add_argument('servicename', metavar='<servicename>',
- help=u._('Service name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
+ parser.add_argument('servicename', metavar='<servicename>',
+ help=u._('Service name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -235,14 +238,15 @@
[docs] def take_action(self, parsed_args):
try:
- data = [('', '')]
+ data = [('', '')]
groups = CLIENT.group_get_all()
if groups:
data = []
for group in groups:
data.append((group.get_name(),
sorted(group.get_services())))
- return ((u._('Group'), u._('Services')), sorted(data))
+ data = convert_lists_to_string(data, parsed_args)
+ return ((u._('Group'), u._('Services')), sorted(data))
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
@@ -280,7 +284,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/host.html b/doc/build/html/_modules/kollacli/commands/host.html
index 5e8018f..1d41739 100644
--- a/doc/build/html/_modules/kollacli/commands/host.html
+++ b/doc/build/html/_modules/kollacli/commands/host.html
@@ -6,7 +6,7 @@
- kollacli.commands.host — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.host — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.host
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 argparse
import getpass
import logging
@@ -72,6 +72,7 @@
from kollacli.api.client import ClientApi
from kollacli.api.exceptions import ClientException
from kollacli.commands.exceptions import CommandError
+from kollacli.common.utils import convert_lists_to_string
from kollacli.common.utils import get_setup_user
from cliff.command import Command
@@ -86,8 +87,8 @@
[docs] def get_parser(self, prog_name):
parser = super(HostAdd, self).get_parser(prog_name)
- parser.add_argument('hostname', metavar='<hostname>',
- help=u._('Host name or ip address'))
+ parser.add_argument('hostname', metavar='<hostname>',
+ help=u._('Host name or ip address'))
return parser
[docs] def take_action(self, parsed_args):
@@ -110,12 +111,12 @@
[docs] def get_parser(self, prog_name):
parser = super(HostDestroy, self).get_parser(prog_name)
- parser.add_argument('hostname', metavar='<hostname | all>',
- help=u._('Host name or ip address or "all"'))
- parser.add_argument('--stop', action='store_true',
- help=u._('Stop rather than kill'))
- parser.add_argument('--includedata', action='store_true',
- help=u._('Destroy data containers'))
+ parser.add_argument('hostname', metavar='<hostname | all>',
+ help=u._('Host name or ip address or "all"'))
+ parser.add_argument('--stop', action='store_true',
+ help=u._('Stop rather than kill'))
+ parser.add_argument('--includedata', action='store_true',
+ help=u._('Destroy data containers'))
return parser
[docs] def take_action(self, parsed_args):
@@ -123,12 +124,12 @@
hostname = parsed_args.hostname.strip()
hostnames = [hostname]
- if hostname == 'all':
+ if hostname == 'all':
hostnames = _get_all_hostnames()
- destroy_type = 'kill'
+ destroy_type = 'kill'
if parsed_args.stop:
- destroy_type = 'stop'
+ destroy_type = 'stop'
include_data = False
if parsed_args.includedata:
include_data = True
@@ -139,14 +140,14 @@
verbose_level, include_data)
status = job.wait()
if verbose_level > 2:
- LOG.info('\n\n' + 80 * '=')
- LOG.info(u._('DEBUG command output:\n{out}')
+ LOG.info('\n\n' + 80 * '=')
+ LOG.info(u._('DEBUG command output:\n{out}')
.format(out=job.get_console_output()))
if status != 0:
- raise CommandError(u._('Job failed:\n{msg}')
+ raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
elif verbose_level > 1:
- # log any ansible warnings
+ # log any ansible warnings
msg = job.get_error_message()
if msg:
LOG.warn(msg)
@@ -162,15 +163,15 @@
[docs] def get_parser(self, prog_name):
parser = super(HostRemove, self).get_parser(prog_name)
- parser.add_argument('hostname', metavar='<hostname | all>',
- help=u._('Host name or "all"'))
+ parser.add_argument('hostname', metavar='<hostname | all>',
+ help=u._('Host name or "all"'))
return parser
[docs] def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostnames = [hostname]
- if hostname == 'all':
+ if hostname == 'all':
hostnames = _get_all_hostnames()
CLIENT.host_remove(hostnames)
@@ -188,8 +189,8 @@
[docs] def get_parser(self, prog_name):
parser = super(HostList, self).get_parser(prog_name)
- parser.add_argument('hostname', nargs='?', metavar='[hostname]',
- help=u._('Host name'))
+ parser.add_argument('hostname', nargs='?', metavar='[hostname]',
+ help=u._('Host name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -209,9 +210,10 @@
for host in hosts:
data.append((host.name, host.get_groups()))
else:
- data.append(('', ''))
+ data.append(('', ''))
- return ((u._('Host'), u._('Groups')), sorted(data))
+ data = convert_lists_to_string(data, parsed_args)
+ return ((u._('Host'), u._('Groups')), sorted(data))
except ClientException as e:
raise CommandError(str(e))
@@ -224,52 +226,52 @@
[docs] def get_parser(self, prog_name):
parser = super(HostCheck, self).get_parser(prog_name)
- parser.add_argument('hostname', metavar='<hostname | all>',
- help=u._('Host name or "all"'))
- parser.add_argument('--predeploy', action='store_true',
- help=u._('Run pre-deploy host checks.'))
+ parser.add_argument('hostname', metavar='<hostname | all>',
+ help=u._('Host name or "all"'))
+ parser.add_argument('--predeploy', action='store_true',
+ help=u._('Run pre-deploy host checks.'))
return parser
[docs] def take_action(self, parsed_args):
try:
hostname = parsed_args.hostname.strip()
hostnames = [hostname]
- if hostname == 'all':
+ if hostname == 'all':
hostnames = _get_all_hostnames()
if parsed_args.predeploy:
- # run pre-deploy checks
+ # run pre-deploy checks
verbose_level = self.app.options.verbose_level
job = CLIENT.async_host_precheck(hostnames, verbose_level)
status = job.wait()
if verbose_level > 2:
- LOG.info('\n\n' + 80 * '=')
- LOG.info(u._('DEBUG command output:\n{out}')
+ LOG.info('\n\n' + 80 * '=')
+ LOG.info(u._('DEBUG command output:\n{out}')
.format(out=job.get_console_output()))
if status != 0:
- raise CommandError(u._('Job failed:\n{msg}')
+ raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
elif verbose_level > 1:
- # log any ansible warnings
+ # log any ansible warnings
msg = job.get_error_message()
if msg:
LOG.warn(msg)
else:
- # just do an ssh check
+ # just do an ssh check
summary = CLIENT.host_ssh_check(hostnames)
all_ok = True
for hostname, info in summary.items():
- status = u._('success')
- msg = ''
- if not info['success']:
- status = u._('failed- ')
- msg = info['msg']
+ status = u._('success')
+ msg = ''
+ if not info['success']:
+ status = u._('failed- ')
+ msg = info['msg']
all_ok = False
- LOG.info(u._('Host {host}: {sts} {msg}')
+ LOG.info(u._('Host {host}: {sts} {msg}')
.format(host=hostname, sts=status, msg=msg))
if not all_ok:
- raise CommandError(u._('Host check failed.'))
+ raise CommandError(u._('Host check failed.'))
except ClientException as e:
raise CommandError(str(e))
except Exception as e:
@@ -281,45 +283,45 @@
[docs] def get_parser(self, prog_name):
parser = super(HostSetup, self).get_parser(prog_name)
- parser.add_argument('hostname', nargs='?',
- metavar='<hostname>', help=u._('Host name'))
- parser.add_argument('--insecure', nargs='?', help=argparse.SUPPRESS)
- parser.add_argument('--file', '-f', nargs='?',
- metavar='<hosts_info_file>',
- help=u._('Absolute path to hosts info file '))
+ parser.add_argument('hostname', nargs='?',
+ metavar='<hostname>', help=u._('Host name'))
+ parser.add_argument('--insecure', nargs='?', help=argparse.SUPPRESS)
+ parser.add_argument('--file', '-f', nargs='?',
+ metavar='<hosts_info_file>',
+ help=u._('Absolute path to hosts info file '))
return parser
[docs] def take_action(self, parsed_args):
try:
if not parsed_args.hostname and not parsed_args.file:
raise CommandError(
- u._('Host name or hosts info file path is required.'))
+ u._('Host name or hosts info file path is required.'))
if parsed_args.hostname and parsed_args.file:
raise CommandError(
- u._('Host name and hosts info file path '
- 'cannot both be present.'))
+ u._('Host name and hosts info file path '
+ 'cannot both be present.'))
if parsed_args.file:
- # multi-host setup via xml file
+ # multi-host setup via xml file
hosts_data = self._get_yml_data(parsed_args.file.strip())
CLIENT.host_setup(hosts_data)
else:
- # single host setup
+ # single host setup
hostname = parsed_args.hostname.strip()
summary = CLIENT.host_ssh_check([hostname])
- if summary[hostname]['success']:
+ if summary[hostname]['success']:
LOG.info(
- u._LI('Skipping setup of host ({host}) as '
- 'ssh check is ok.').format(host=hostname))
+ u._LI('Skipping setup of host ({host}) as '
+ 'ssh check is ok.').format(host=hostname))
return True
if parsed_args.insecure:
password = parsed_args.insecure.strip()
else:
password = getpass.getpass(
- u._('{name} password for {host}: ')
+ u._('{name} password for {host}: ')
.format(name=get_setup_user(), host=hostname))
- CLIENT.host_setup({hostname: {'password': password}})
+ CLIENT.host_setup({hostname: {'password': password}})
except ClientException as e:
raise CommandError(str(e))
@@ -329,15 +331,15 @@
def _get_yml_data(self, yml_path):
if not os.path.isfile(yml_path):
raise CommandError(
- u._('No file exists at {path}. An absolute file path is '
- 'required.').format(path=yml_path))
+ u._('No file exists at {path}. An absolute file path is '
+ 'required.').format(path=yml_path))
- with open(yml_path, 'r') as hosts_file:
+ with open(yml_path, 'r') as hosts_file:
file_data = hosts_file.read()
hosts_info = yaml.safe_load(file_data)
if not hosts_info:
- raise CommandError(u._('{path} is empty.').format(path=yml_path))
+ raise CommandError(u._('{path} is empty.').format(path=yml_path))
return hosts_info
@@ -380,7 +382,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/password.html b/doc/build/html/_modules/kollacli/commands/password.html
index a8a2554..2cffdf2 100644
--- a/doc/build/html/_modules/kollacli/commands/password.html
+++ b/doc/build/html/_modules/kollacli/commands/password.html
@@ -6,7 +6,7 @@
- kollacli.commands.password — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.password — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,21 +47,22 @@
Source code for kollacli.commands.password
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 argparse
import getpass
+import os
import traceback
import kollacli.i18n as u
@@ -76,13 +77,13 @@
[docs]class PasswordSet(Command):
- "Password Set"
+ "Password Set"
[docs] def get_parser(self, prog_name):
parser = super(PasswordSet, self).get_parser(prog_name)
- parser.add_argument('passwordname', metavar='<passwordname>',
- help=u._('Password name'))
- parser.add_argument('--insecure', nargs='?', help=argparse.SUPPRESS)
+ parser.add_argument('passwordname', metavar='<passwordname>',
+ help=u._('Password name'))
+ parser.add_argument('--insecure', nargs='?', help=argparse.SUPPRESS)
return parser
[docs] def take_action(self, parsed_args):
@@ -91,25 +92,64 @@
if parsed_args.insecure:
password = parsed_args.insecure.strip()
else:
- password = getpass.getpass(u._('Password: ')).strip()
- passtwo = getpass.getpass(u._('Retype Password: ')).strip()
+ password = getpass.getpass(u._('Password: ')).strip()
+ passtwo = getpass.getpass(u._('Retype Password: ')).strip()
if password != passtwo:
- raise CommandError(u._('Passwords do not match'))
+ raise CommandError(u._('Passwords do not match'))
CLIENT.password_set(password_name, password)
except Exception:
raise Exception(traceback.format_exc())
+
+[docs]class PasswordSetKey(Command):
+ "Password Set SSH Key"
+
+[docs] def get_parser(self, prog_name):
+ parser = super(PasswordSetKey, self).get_parser(prog_name)
+ parser.add_argument('passwordname', metavar='<passwordname>',
+ help=u._('Password name'))
+ parser.add_argument('privatekeypath', metavar='<privatekeypath>',
+ help=u._('Path to private key file'))
+ parser.add_argument('publickeypath', metavar='<publickeypath>',
+ help=u._('Path to public key file'))
+ return parser
+
+[docs] def take_action(self, parsed_args):
+ try:
+ password_name = parsed_args.passwordname.strip()
+ private_keypath = parsed_args.privatekeypath.strip()
+ private_keypath = os.path.abspath(private_keypath)
+ public_keypath = parsed_args.publickeypath.strip()
+ public_keypath = os.path.abspath(public_keypath)
+
+ if not os.path.isfile(private_keypath):
+ raise(CommandError(u._('Private key file not found: {path}')
+ .format(path=private_keypath)))
+ if not os.path.isfile(public_keypath):
+ raise(CommandError(u._('Public key file not found: {path}')
+ .format(path=public_keypath)))
+
+ with open(private_keypath, 'r') as f:
+ private_key = f.read()
+ with open(public_keypath, 'r') as f:
+ public_key = f.read()
+ CLIENT.password_set_sshkey(password_name, private_key.strip(),
+ public_key.strip())
+
+ except Exception:
+ raise Exception(traceback.format_exc())
+
[docs]class PasswordClear(Command):
- "Password Clear"
+ "Password Clear"
[docs] def get_parser(self, prog_name):
parser = super(PasswordClear, self).get_parser(prog_name)
- parser.add_argument('passwordname', metavar='<passwordname>',
- help=u._('Password name'))
+ parser.add_argument('passwordname', metavar='<passwordname>',
+ help=u._('Password name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -130,9 +170,19 @@
data = []
for password_name in password_names:
- data.append((password_name, '-'))
+ data.append((password_name, '-'))
- return ((u._('Password Name'), u._('Password')), data)
+ return ((u._('Password Name'), u._('Password')), data)
+ except Exception:
+ raise Exception(traceback.format_exc())
+
+
+
@@ -168,7 +218,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/property.html b/doc/build/html/_modules/kollacli/commands/property.html
index e28a5fe..ddac1ea 100644
--- a/doc/build/html/_modules/kollacli/commands/property.html
+++ b/doc/build/html/_modules/kollacli/commands/property.html
@@ -6,7 +6,7 @@
- kollacli.commands.property — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.property — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.property
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 traceback
import kollacli.i18n as u
@@ -76,27 +76,27 @@
def _get_names(args_list):
csv_list = args_list[0].strip()
- names = utils.convert_to_unicode(csv_list).split(',')
- if 'all' in names:
+ names = utils.convert_to_unicode(csv_list).split(',')
+ if 'all' in names:
names = None
return names
[docs]class PropertySet(Command):
- "Property Set"
+ "Property Set"
[docs] def get_parser(self, prog_name):
parser = super(PropertySet, self).get_parser(prog_name)
- parser.add_argument('propertyname', metavar='<propertyname>',
- help=u._('Property name'))
- parser.add_argument('propertyvalue', metavar='<propertyvalue',
- help=u._('Property value'))
- parser.add_argument('--hosts', nargs=1,
- metavar='<host_list>',
- help=u._('Property host list'))
- parser.add_argument('--groups', nargs=1,
- metavar='<group_list>',
- help=u._('Property group list'))
+ parser.add_argument('propertyname', metavar='<propertyname>',
+ help=u._('Property name'))
+ parser.add_argument('propertyvalue', metavar='<propertyvalue',
+ help=u._('Property value'))
+ parser.add_argument('--hosts', nargs=1,
+ metavar='<host_list>',
+ help=u._('Property host list'))
+ parser.add_argument('--groups', nargs=1,
+ metavar='<group_list>',
+ help=u._('Property group list'))
return parser
[docs] def take_action(self, parsed_args):
@@ -109,40 +109,40 @@
if parsed_args.hosts:
if parsed_args.groups:
raise CommandError(
- u._('Invalid to use both hosts and groups arguments '
- 'together.'))
+ u._('Invalid to use both hosts and groups arguments '
+ 'together.'))
host_names = _get_names(parsed_args.hosts)
CLIENT.property_set(property_dict,
- 'host', host_names)
+ 'host', host_names)
elif parsed_args.groups:
group_names = _get_names(parsed_args.groups)
CLIENT.property_set(property_dict,
- 'group', group_names)
+ 'group', group_names)
else:
CLIENT.property_set(property_dict,
- 'global')
+ 'global')
except Exception:
raise Exception(traceback.format_exc())
[docs]class PropertyClear(Command):
- "Property Clear"
+ "Property Clear"
[docs] def get_parser(self, prog_name):
parser = super(PropertyClear, self).get_parser(prog_name)
- parser.add_argument('propertyname', metavar='<propertyname>',
- help=u._('Property name'))
- parser.add_argument('--hosts', nargs=1,
- metavar='<host_list>',
- help=u._('Property host list'))
- parser.add_argument('--groups', nargs=1,
- metavar='<group_list>',
- help=u._('Property group list'))
+ parser.add_argument('propertyname', metavar='<propertyname>',
+ help=u._('Property name'))
+ parser.add_argument('--hosts', nargs=1,
+ metavar='<host_list>',
+ help=u._('Property host list'))
+ parser.add_argument('--groups', nargs=1,
+ metavar='<group_list>',
+ help=u._('Property group list'))
return parser
[docs] def take_action(self, parsed_args):
@@ -154,20 +154,20 @@
if parsed_args.hosts:
if parsed_args.groups:
raise CommandError(
- u._('Invalid to use both hosts and groups arguments '
- 'together.'))
+ u._('Invalid to use both hosts and groups arguments '
+ 'together.'))
host_names = _get_names(parsed_args.hosts)
- CLIENT.property_clear(property_list, 'host',
+ CLIENT.property_clear(property_list, 'host',
host_names)
elif parsed_args.groups:
group_names = _get_names(parsed_args.groups)
- CLIENT.property_clear(property_list, 'group',
+ CLIENT.property_clear(property_list, 'group',
group_names)
else:
- CLIENT.property_clear(property_list, 'global')
+ CLIENT.property_clear(property_list, 'global')
except Exception:
raise Exception(traceback.format_exc())
@@ -187,16 +187,16 @@
[docs] def get_parser(self, prog_name):
parser = super(PropertyList, self).get_parser(prog_name)
- parser.add_argument('--all', action='store_true',
- help=u._('List all properties'))
- parser.add_argument('--long', action='store_true',
- help=u._('Show all property attributes'))
- parser.add_argument('--hosts', nargs=1,
- metavar='<host_list>',
- help=u._('Property host list'))
- parser.add_argument('--groups', nargs=1,
- metavar='<group_list>',
- help=u._('Property group list'))
+ parser.add_argument('--all', action='store_true',
+ help=u._('List all properties'))
+ parser.add_argument('--long', action='store_true',
+ help=u._('Show all property attributes'))
+ parser.add_argument('--hosts', nargs=1,
+ metavar='<host_list>',
+ help=u._('Property host list'))
+ parser.add_argument('--groups', nargs=1,
+ metavar='<group_list>',
+ help=u._('Property group list'))
return parser
[docs] def take_action(self, parsed_args):
@@ -209,25 +209,25 @@
if parsed_args.hosts:
if parsed_args.groups:
raise CommandError(
- u._('Invalid to use both hosts and groups arguments '
- 'together.'))
+ u._('Invalid to use both hosts and groups arguments '
+ 'together.'))
self.is_global = False
- self.list_type = u._('Host')
+ self.list_type = u._('Host')
host_names = _get_names(parsed_args.hosts)
- property_list = CLIENT.property_get('host',
+ property_list = CLIENT.property_get('host',
host_names)
elif parsed_args.groups:
self.is_global = False
- self.list_type = u._('Group')
+ self.list_type = u._('Group')
group_names = _get_names(parsed_args.groups)
- property_list = CLIENT.property_get('group',
+ property_list = CLIENT.property_get('group',
group_names)
else:
- property_list = CLIENT.property_get('global')
+ property_list = CLIENT.property_get('global')
data = self._get_list_data(property_list)
header = self._get_list_header()
@@ -240,21 +240,21 @@
header = None
if self.is_long_flag:
if self.is_global:
- header = (u._('OVR'),
- u._('Property Name'), u._('Property Value'),
- u._('Original Value'))
+ header = (u._('OVR'),
+ u._('Property Name'), u._('Property Value'),
+ u._('Original Value'))
else:
- header = (u._('OVR'),
- u._('Property Name'), u._('Property Value'),
- u._('Original Value'),
+ header = (u._('OVR'),
+ u._('Property Name'), u._('Property Value'),
+ u._('Original Value'),
self.list_type)
else:
if self.is_global:
- header = (u._('OVR'),
- u._('Property Name'), u._('Property Value'))
+ header = (u._('OVR'),
+ u._('Property Name'), u._('Property Value'))
else:
- header = (u._('OVR'),
- u._('Property Name'), u._('Property Value'),
+ header = (u._('OVR'),
+ u._('Property Name'), u._('Property Value'),
self.list_type)
return header
@@ -274,16 +274,16 @@
if not include_prop:
continue
- ovr_global = '-'
- ovr_group = '-'
- ovr_host = '-'
+ ovr_global = '-'
+ ovr_group = '-'
+ ovr_host = '-'
if prop.ovr_global:
- ovr_global = '*'
+ ovr_global = '*'
if prop.ovr_group:
- ovr_group = 'G'
+ ovr_group = 'G'
if prop.ovr_host:
- ovr_host = 'H'
+ ovr_host = 'H'
prop_ovr = ovr_global + ovr_group + ovr_host
@@ -303,14 +303,14 @@
else:
if self.is_long_flag:
if self.is_global:
- data.append(('', '', '', ''))
+ data.append(('', '', '', ''))
else:
- data.append(('', '', '', '', ''))
+ data.append(('', '', '', '', ''))
else:
if self.is_global:
- data.append(('', '', ''))
+ data.append(('', '', ''))
else:
- data.append(('', '', '', ''))
+ data.append(('', '', '', ''))
return data
@@ -346,7 +346,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/service.html b/doc/build/html/_modules/kollacli/commands/service.html
index b3f8e35..f927bab 100644
--- a/doc/build/html/_modules/kollacli/commands/service.html
+++ b/doc/build/html/_modules/kollacli/commands/service.html
@@ -6,7 +6,7 @@
- kollacli.commands.service — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.service — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.service
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 traceback
import kollacli.i18n as u
@@ -67,6 +67,7 @@
from kollacli.api.client import ClientApi
from kollacli.api.exceptions import ClientException
from kollacli.commands.exceptions import CommandError
+from kollacli.common.utils import convert_lists_to_string
from cliff.command import Command
from cliff.lister import Lister
@@ -83,10 +84,10 @@
[docs] def get_parser(self, prog_name):
parser = super(ServiceAddGroup, self).get_parser(prog_name)
- parser.add_argument('servicename', metavar='<servicename>',
- help=u._('Service name'))
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
+ parser.add_argument('servicename', metavar='<servicename>',
+ help=u._('Service name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -108,10 +109,10 @@
[docs] def get_parser(self, prog_name):
parser = super(ServiceRemoveGroup, self).get_parser(prog_name)
- parser.add_argument('servicename', metavar='<servicename>',
- help=u._('Service name'))
- parser.add_argument('groupname', metavar='<groupname>',
- help=u._('Group name'))
+ parser.add_argument('servicename', metavar='<servicename>',
+ help=u._('Service name'))
+ parser.add_argument('groupname', metavar='<groupname>',
+ help=u._('Group name'))
return parser
[docs] def take_action(self, parsed_args):
@@ -133,23 +134,24 @@
[docs] def take_action(self, parsed_args):
try:
- data = [('', '')]
+ data = [('', '')]
services = CLIENT.service_get_all()
if services:
data = []
for service in services:
- inh_str = '-'
+ inh_str = '-'
groupnames = sorted(service.get_groups())
parentname = service.get_parent()
if parentname:
- # this is a subservice
- inh_str = 'no'
+ # this is a subservice
+ inh_str = 'no'
if not groupnames:
- # sub-service is inheriting groups from parent
- inh_str = 'yes'
- groupnames = ''
+ # sub-service is inheriting groups from parent
+ inh_str = 'yes'
+ groupnames = ''
data.append((service.name, groupnames, inh_str))
- return ((u._('Service'), u._('Groups'), u._('Inherited')),
+ data = convert_lists_to_string(data, parsed_args)
+ return ((u._('Service'), u._('Groups'), u._('Inherited')),
sorted(data))
except ClientException as e:
raise CommandError(str(e))
@@ -162,15 +164,16 @@
[docs] def take_action(self, parsed_args):
try:
- data = [('', '')]
+ data = [('', '')]
services = CLIENT.service_get_all()
if services:
data = []
for service in services:
if not service.get_parent():
- # this is a service, not a subservice
+ # this is a service, not a subservice
data.append((service.name, service.get_children()))
- return ((u._('Service'), u._('Sub-Services')), sorted(data))
+ data = convert_lists_to_string(data, parsed_args)
+ return ((u._('Service'), u._('Sub-Services')), sorted(data))
except ClientException as e:
raise CommandError(str(e))
@@ -209,7 +212,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/support.html b/doc/build/html/_modules/kollacli/commands/support.html
index 359d890..7b4087b 100644
--- a/doc/build/html/_modules/kollacli/commands/support.html
+++ b/doc/build/html/_modules/kollacli/commands/support.html
@@ -6,7 +6,7 @@
- kollacli.commands.support — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.support — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.support
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 cliff.command import Command
from kollacli.api.client import ClientApi
import kollacli.i18n as u
@@ -81,9 +81,9 @@
[docs] def take_action(self, parsed_args):
try:
dump_path = CLIENT.support_dump(tempfile.gettempdir())
- LOG.info(u._('Dump successful to {path}').format(path=dump_path))
+ LOG.info(u._('Dump successful to {path}').format(path=dump_path))
except Exception:
- msg = (u._('Dump failed: {reason}')
+ msg = (u._('Dump failed: {reason}')
.format(reason=traceback.format_exc()))
raise Exception(msg)
@@ -119,7 +119,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/commands/upgrade.html b/doc/build/html/_modules/kollacli/commands/upgrade.html
index e766033..4599502 100644
--- a/doc/build/html/_modules/kollacli/commands/upgrade.html
+++ b/doc/build/html/_modules/kollacli/commands/upgrade.html
@@ -6,7 +6,7 @@
- kollacli.commands.upgrade — kollacli 3.0.1.dev435 documentation
+ kollacli.commands.upgrade — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.commands.upgrade
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import traceback
@@ -88,13 +88,13 @@
job = CLIENT.async_upgrade(verbose_level)
status = job.wait()
if verbose_level > 2:
- LOG.info('\n\n' + 80 * '=')
- LOG.info(u._('DEBUG command output:\n{out}')
+ LOG.info('\n\n' + 80 * '=')
+ LOG.info(u._('DEBUG command output:\n{out}')
.format(out=job.get_console_output()))
if status == 0:
- LOG.info(u._('Success'))
+ LOG.info(u._('Success'))
else:
- raise CommandError(u._('Job failed:\n{msg}')
+ raise CommandError(u._('Job failed:\n{msg}')
.format(msg=job.get_error_message()))
except Exception:
@@ -132,7 +132,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/ansible/actions.html b/doc/build/html/_modules/kollacli/common/ansible/actions.html
index 942e9ee..df21fcd 100644
--- a/doc/build/html/_modules/kollacli/common/ansible/actions.html
+++ b/doc/build/html/_modules/kollacli/common/ansible/actions.html
@@ -6,7 +6,7 @@
- kollacli.common.ansible.actions — kollacli 3.0.1.dev435 documentation
+ kollacli.common.ansible.actions — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.ansible.actions
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import os
@@ -70,6 +70,7 @@
from kollacli.api.exceptions import NotInInventory
from kollacli.common.ansible.playbook import AnsiblePlaybook
from kollacli.common.inventory import Inventory
+from kollacli.common.passwords import get_empty_password_values
from kollacli.common import properties
from kollacli.common.properties import AnsibleProperties
from kollacli.common.utils import get_kolla_etc
@@ -88,26 +89,26 @@
or killed. That will be determined by the destroy_type,
which can either be 'stop' or 'kill'.
'''
- playbook_name = 'host_destroy_no_data.yml'
+ playbook_name = 'host_destroy_no_data.yml'
if include_data:
- playbook_name = 'host_destroy.yml'
+ playbook_name = 'host_destroy.yml'
- LOG.info(u._LI('Please be patient as this may take a while.'))
+ LOG.info(u._LI('Please be patient as this may take a while.'))
ansible_properties = properties.AnsibleProperties()
base_distro = \
- ansible_properties.get_property('kolla_base_distro')
+ ansible_properties.get_property('kolla_base_distro')
install_type = \
- ansible_properties.get_property('kolla_install_type')
- container_prefix = base_distro + '-' + install_type
+ ansible_properties.get_property('kolla_install_type')
+ container_prefix = base_distro + '-' + install_type
kollacli_home = get_kollacli_home()
playbook = AnsiblePlaybook()
playbook.playbook_path = os.path.join(kollacli_home,
- 'ansible/' + playbook_name)
+ 'ansible/' + playbook_name)
- # 'hosts' is defined as 'all' in the playbook yml code, but inventory
- # filtering will subset that down to the hosts in playbook.hosts.
- playbook.extra_vars = 'prefix=' + container_prefix + \
- ' destroy_type=' + destroy_type
+ # 'hosts' is defined as 'all' in the playbook yml code, but inventory
+ # filtering will subset that down to the hosts in playbook.hosts.
+ playbook.extra_vars = 'prefix=' + container_prefix + \
+ ' destroy_type=' + destroy_type
playbook.hosts = hostnames
if verbose_level <= 1:
playbook.print_output = False
@@ -121,7 +122,8 @@
playbook = AnsiblePlaybook()
kolla_home = get_kolla_home()
playbook.playbook_path = os.path.join(kolla_home,
- 'ansible/site.yml')
+ 'ansible/site.yml')
+ playbook.extra_vars = 'action=deploy'
playbook.hosts = hostnames
playbook.serial = serial_flag
@@ -135,15 +137,15 @@
[docs]def precheck(hostnames, verbose_level=1):
'''run check playbooks on a set of hosts'''
- playbook_name = 'prechecks.yml'
+ playbook_name = 'prechecks_preinstall.yml'
kolla_home = get_kolla_home()
playbook = AnsiblePlaybook()
playbook.playbook_path = os.path.join(kolla_home,
- 'ansible/' + playbook_name)
+ 'ansible/' + playbook_name)
- # define 'hosts' to be all, but inventory filtering will subset
- # that down to the hosts in playbook.hosts.
- playbook.extra_vars = 'hosts=all'
+ # define 'hosts' to be all, but inventory filtering will subset
+ # that down to the hosts in playbook.hosts.
+ playbook.extra_vars = 'hosts=all'
playbook.hosts = hostnames
playbook.print_output = True
playbook.verbose_level = verbose_level
@@ -155,8 +157,8 @@
playbook = AnsiblePlaybook()
kolla_home = get_kolla_home()
playbook.playbook_path = os.path.join(kolla_home,
- 'ansible/site.yml')
- playbook.extra_vars = 'action=upgrade'
+ 'ansible/site.yml')
+ playbook.extra_vars = 'action=upgrade'
playbook.print_output = True
playbook.verbose_level = verbose_level
job = playbook.run()
@@ -167,38 +169,49 @@
properties = AnsibleProperties()
inventory = Inventory.load()
- # if we are doing a targeted host deploy make sure we are doing it
- # to only compute nodes
+ # check that password file has no empty password values
+ empty_keys = get_empty_password_values()
+ if empty_keys:
+ raise InvalidConfiguration(
+ u._('Deploy failed. There are empty password values '
+ 'in {etc}passwords.yml. '
+ 'Please run kollacli password init or '
+ 'kollacli password set(key) to correct them. '
+ '\nEmpty passwords: '
+ '{keys}').format(etc=get_kolla_etc(), keys=empty_keys))
+
+ # if we are doing a targeted host deploy make sure we are doing it
+ # to only compute nodes
if playbook.hosts:
inventory.validate_hostnames(playbook.hosts)
host_groups = inventory.get_host_groups()
invalid_host_list = []
for host in playbook.hosts:
groups = host_groups.get(host, None)
- if not groups or len(groups) != 1 or 'compute' not in groups:
+ if not groups or len(groups) != 1 or 'compute' not in groups:
invalid_host_list.append(host)
if len(invalid_host_list) > 0:
raise InvalidArgument(
- u._('Invalid hosts for host targeted deploy. '
- 'Hosts must be in the compute group only.'
- 'Invalid hosts: {hosts}')
+ u._('Invalid hosts for host targeted deploy. '
+ 'Hosts must be in the compute group only.'
+ 'Invalid hosts: {hosts}')
.format(hosts=invalid_host_list))
- # cannot have both groups and hosts
+ # cannot have both groups and hosts
if playbook.hosts and playbook.groups:
raise InvalidArgument(
- u._('Hosts and Groups arguments cannot '
- 'both be present at the same time.'))
+ u._('Hosts and Groups arguments cannot '
+ 'both be present at the same time.'))
- # verify that all services exists
+ # verify that all services exists
if playbook.services:
for service in playbook.services:
valid_service = inventory.get_service(service)
if not valid_service:
- raise NotInInventory(u._('Service'), service)
+ raise NotInInventory(u._('Service'), service)
- # check that every group with enabled services
- # has hosts associated to it
+ # check that every group with enabled services
+ # has hosts associated to it
group_services = inventory.get_group_services()
failed_groups = []
failed_services = []
@@ -218,29 +231,29 @@
if len(failed_groups) > 0:
raise InvalidConfiguration(
- u._('Deploy failed. '
- 'Groups: {groups} with enabled '
- 'services : {services} '
- 'have no associated hosts')
+ u._('Deploy failed. '
+ 'Groups: {groups} with enabled '
+ 'services : {services} '
+ 'have no associated hosts')
.format(groups=failed_groups, services=failed_services))
- # check that ring files are in /etc/kolla/config/swift if
- # swift is enabled
- expected_files = ['account.ring.gz',
- 'container.ring.gz',
- 'object.ring.gz']
- is_enabled = properties.get_property('enable_swift')
+ # check that ring files are in /etc/kolla/config/swift if
+ # swift is enabled
+ expected_files = ['account.ring.gz',
+ 'container.ring.gz',
+ 'object.ring.gz']
+ is_enabled = properties.get_property('enable_swift')
if is_string_true(is_enabled):
- path_pre = os.path.join(get_kolla_etc(), 'config', 'swift')
+ path_pre = os.path.join(get_kolla_etc(), 'config', 'swift')
for expected_file in expected_files:
path = os.path.join(path_pre, expected_file)
if not os.path.isfile(path):
msg = u._(
- 'Deploy failed. '
- 'Swift is enabled but ring buffers have '
- 'not yet been set up. Please see the '
- 'documentation for swift configuration '
- 'instructions.')
+ 'Deploy failed. '
+ 'Swift is enabled but ring buffers have '
+ 'not yet been set up. Please see the '
+ 'documentation for swift configuration '
+ 'instructions.')
raise InvalidConfiguration(msg)
@@ -250,13 +263,13 @@
sub_service = inventory.get_sub_service(servicename)
if sub_service is not None:
- enabled_property = 'enable_' + servicename.replace('-', '_')
+ enabled_property = 'enable_' + servicename.replace('-', '_')
is_enabled = properties.get_property(enabled_property)
if is_string_true(is_enabled):
service_enabled = True
- # Only bother looking at the parent service if the sub service
- # is enabled.
+ # Only bother looking at the parent service if the sub service
+ # is enabled.
if service_enabled:
servicename = sub_service.get_parent_servicename()
if servicename is None:
@@ -264,7 +277,7 @@
service = inventory.get_service(servicename)
if service is not None:
- enabled_property = 'enable_' + servicename.replace('-', '_')
+ enabled_property = 'enable_' + servicename.replace('-', '_')
is_enabled = properties.get_property(enabled_property)
if is_string_true(is_enabled):
service_enabled = True
@@ -315,7 +328,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/ansible/job.html b/doc/build/html/_modules/kollacli/common/ansible/job.html
index 502d226..4df4419 100644
--- a/doc/build/html/_modules/kollacli/common/ansible/job.html
+++ b/doc/build/html/_modules/kollacli/common/ansible/job.html
@@ -6,7 +6,7 @@
- kollacli.common.ansible.job — kollacli 3.0.1.dev435 documentation
+ kollacli.common.ansible.job — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,26 +47,26 @@
Source code for kollacli.common.ansible.job
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 fcntl
import json
import logging
import os
import pwd
import re
-import subprocess # nosec
+import subprocess # nosec
import tempfile
import time
@@ -86,16 +86,16 @@
LINE_LENGTH = 80
-PIPE_NAME = '.kolla_pipe'
+PIPE_NAME = '.kolla_pipe'
-# action defs
-ACTION_PLAY_START = 'play_start'
-ACTION_TASK_START = 'task_start'
-ACTION_TASK_END = 'task_end'
-ACTION_INCLUDE_FILE = 'includefile'
-ACTION_STATS = 'stats'
+# action defs
+ACTION_PLAY_START = 'play_start'
+ACTION_TASK_START = 'task_start'
+ACTION_TASK_END = 'task_end'
+ACTION_INCLUDE_FILE = 'includefile'
+ACTION_STATS = 'stats'
-ANSIBLE_1_OR_MORE = 'One or more items failed'
+ANSIBLE_1_OR_MORE = 'One or more items failed'
[docs]class AnsibleJob(object):
@@ -107,30 +107,30 @@
self._print_output = print_output
self._temp_inv_path = inventory_path
- self._fragment = ''
+ self._fragment = ''
self._is_first_packet = True
self._fifo_path = os.path.join(
tempfile.gettempdir(),
- 'kolla_%s' % deploy_id,
- '%s' % PIPE_NAME)
+ 'kolla_%s' % deploy_id,
+ '%s' % PIPE_NAME)
self._fifo_fd = None
self._process = None
self._process_std_err = None
self._errors = []
- self._cmd_output = ''
+ self._cmd_output = ''
self._kill_uname = None
- self._ansible_lock = Lock(get_ansible_lock_path(), 'ansible_job')
+ self._ansible_lock = Lock(get_ansible_lock_path(), 'ansible_job')
[docs] def run(self):
try:
locked = self._ansible_lock.wait_acquire()
if not locked:
raise Exception(
- u._('unable to get lock: {lock}, to run '
- 'ansible job: {cmd} ')
+ u._('unable to get lock: {lock}, to run '
+ 'ansible job: {cmd} ')
.format(lock=get_ansible_lock_path(), cmd=self._command))
- # create and open named pipe, must be owned by kolla group
+ # create and open named pipe, must be owned by kolla group
os.mkfifo(self._fifo_path)
_, grp_id = get_admin_uids()
os.chown(self._fifo_path, os.getuid(), grp_id)
@@ -138,13 +138,13 @@
self._fifo_fd = os.open(self._fifo_path,
os.O_RDONLY | os.O_NONBLOCK)
- self._process = subprocess.Popen(self._command, # nosec
+ self._process = subprocess.Popen(self._command, # nosec
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
- # setup stdout to be read without blocking
- LOG.debug('process pid: %s' % self._process.pid)
+ # setup stdout to be read without blocking
+ LOG.debug('process pid: %s' % self._process.pid)
flags = fcntl.fcntl(self._process.stdout, fcntl.F_GETFL)
fcntl.fcntl(self._process.stdout, fcntl.F_SETFL,
(flags | os.O_NONBLOCK))
@@ -176,12 +176,12 @@
status = self._process.poll()
self._read_from_callback()
out = self._read_stream(self._process.stdout)
- self._cmd_output = ''.join([self._cmd_output, out])
+ self._cmd_output = ''.join([self._cmd_output, out])
if status is not None:
- # job has completed
+ # job has completed
if self._kill_uname:
status = 2
- msg = (u._('Job killed by user ({name})')
+ msg = (u._('Job killed by user ({name})')
.format(name=self._kill_uname))
self._errors = [msg]
else:
@@ -189,7 +189,7 @@
if status != 0:
status = 1
if not self._process_std_err:
- # read stderr from process
+ # read stderr from process
std_err = self._read_stream(self._process.stderr)
self._process_std_err = std_err.strip()
self._cleanup()
@@ -197,11 +197,11 @@
[docs] def get_error_message(self):
""""get error message"""
- msg = ''
+ msg = ''
for error in self._errors:
- msg = ''.join([msg, error, '\n'])
+ msg = ''.join([msg, error, '\n'])
- # if no error from the callback, check the process error
+ # if no error from the callback, check the process error
if ANSIBLE_1_OR_MORE in msg:
msg = self._get_msg_from_cmdout(msg)
if not msg:
@@ -221,25 +221,25 @@
The process pid is owned by root, so
that is not killable. Need to kill all its children.
"""
- # the kill must be run as the kolla user so the
- # kolla_actions program must be used.
+ # the kill must be run as the kolla user so the
+ # kolla_actions program must be used.
try:
actions_path = get_kolla_actions_path()
kolla_user = get_admin_user()
- cmd_prefix = ('/usr/bin/sudo -u %s %s job -t -p '
+ cmd_prefix = ('/usr/bin/sudo -u %s %s job -t -p '
% (kolla_user, actions_path))
- # kill the children from largest to smallest pids.
+ # kill the children from largest to smallest pids.
child_pids = PidManager.get_child_pids(self._process.pid)
for child_pid in sorted(child_pids, reverse=True):
- cmd = ''.join([cmd_prefix, child_pid])
+ cmd = ''.join([cmd_prefix, child_pid])
err_msg, output = run_cmd(cmd, print_output=False)
if err_msg:
- LOG.debug('kill failed: %s %s' % (err_msg, output))
+ LOG.debug('kill failed: %s %s' % (err_msg, output))
else:
- LOG.debug('kill succeeded: %s' % child_pid)
+ LOG.debug('kill succeeded: %s' % child_pid)
- # record the name of user who killed the job
+ # record the name of user who killed the job
cur_uid = os.getuid()
self._kill_uname = pwd.getpwuid(cur_uid)[0]
finally:
@@ -262,33 +262,33 @@
"msg": "IOError: [Errno 2] No such file or directory:
u'/etc/kolla/config/aodh.conf'"}\n
"""
- fail_key = '\nfailed: '
- hostnames = re.findall(fail_key + '\[(.+?)]', self._cmd_output)
- msgs = re.findall(fail_key + '.+ => (.+?)\n', self._cmd_output)
+ fail_key = '\nfailed: '
+ hostnames = re.findall(fail_key + '\[(.+?)]', self._cmd_output)
+ msgs = re.findall(fail_key + '.+ => (.+?)\n', self._cmd_output)
for i in range(0, min(len(hostnames), len(msgs))):
- err = ''
+ err = ''
hostname = hostnames[i]
ans_dict_str = msgs[i]
try:
ans_dict = json.loads(ans_dict_str)
- err = ans_dict.get('msg', '')
+ err = ans_dict.get('msg', '')
except Exception as e:
- LOG.warn('Exception reading cmd_out ansible dictionary: %s'
+ LOG.warn('Exception reading cmd_out ansible dictionary: %s'
% str(e))
- msg = ''.join([msg, 'Host: ', hostname, ', ', err, '\n'])
+ msg = ''.join([msg, 'Host: ', hostname, ', ', err, '\n'])
return msg
def _read_stream(self, stream):
- out = ''
+ out = ''
if stream and not stream.closed:
try:
out = safe_decode(stream.read())
- except IOError: # nosec
- # error can happen if stream is empty
+ except IOError: # nosec
+ # error can happen if stream is empty
pass
if out is None:
- out = ''
+ out = ''
return out
def _log_lines(self, lines):
@@ -303,10 +303,10 @@
- close stdout and stderr
- close and delete named pipe (fifo)
"""
- # try to clear the ansible lock
+ # try to clear the ansible lock
self._ansible_lock.release()
- # close the process's stdout and stderr streams
+ # close the process's stdout and stderr streams
if (self._process and self._process.stdout and not
self._process.stdout.closed):
self._process.stdout.close()
@@ -314,17 +314,17 @@
self._process.stderr.closed):
self._process.stderr.close()
- # close and delete the named pipe (fifo)
+ # close and delete the named pipe (fifo)
if self._fifo_fd:
try:
os.close(self._fifo_fd)
- except OSError: # nosec
- # fifo already closed
+ except OSError: # nosec
+ # fifo already closed
pass
if self._fifo_path and os.path.exists(self._fifo_path):
os.remove(self._fifo_path)
- # delete temp inventory file
+ # delete temp inventory file
remove_temp_inventory(self._temp_inv_path)
def _read_from_callback(self):
@@ -333,19 +333,19 @@
try:
data = os.read(self._fifo_fd, 10000000)
data = safe_decode(data)
- except OSError: # nosec
- # error can happen if fifo is empty
+ except OSError: # nosec
+ # error can happen if fifo is empty
pass
if data:
- LOG.debug('callback packets: %s' % data)
+ LOG.debug('callback packets: %s' % data)
packets = self._deserialize_packets(data)
for packet in packets:
formatted_data = self._format_packet(packet)
- lines = formatted_data.split('\n')
+ lines = formatted_data.split('\n')
self._log_lines(lines)
def _format_packet(self, packet):
- action = packet['action']
+ action = packet['action']
if action == ACTION_INCLUDE_FILE:
return self._format_include_file(packet)
elif action == ACTION_PLAY_START:
@@ -357,110 +357,110 @@
elif action == ACTION_TASK_START:
return self._format_task_start(packet)
else:
- raise Exception(u._('Invalid action [{action}] from callback')
+ raise Exception(u._('Invalid action [{action}] from callback')
.format(action=action))
def _format_include_file(self, packet):
- return 'included: %s' % packet['filename']
+ return 'included: %s' % packet['filename']
def _format_play_start(self, packet):
- msg = '\n' + self._add_filler('PLAY ', LINE_LENGTH, '*')
+ msg = '\n' + self._add_filler('PLAY ', LINE_LENGTH, '*')
if self._is_first_packet:
- msg += '\nPlaybook: %s' % packet['playbook']
+ msg += '\nPlaybook: %s' % packet['playbook']
self._is_first_packet = False
return msg
def _format_stats(self, packet):
- # each element is a dictionary with host as key
- msg = '\n' + self._add_filler('PLAY RECAP ', LINE_LENGTH, '*')
- processed = packet['processed']
- ok = packet['ok']
- changed = packet['changed']
- unreachable = packet['unreachable']
- failures = packet['failures']
+ # each element is a dictionary with host as key
+ msg = '\n' + self._add_filler('PLAY RECAP ', LINE_LENGTH, '*')
+ processed = packet['processed']
+ ok = packet['ok']
+ changed = packet['changed']
+ unreachable = packet['unreachable']
+ failures = packet['failures']
for host in processed:
- hostline = '\n%s' % self._add_filler(host, 28, ' ')
- hostline += (': ok=%s'
- % self._add_filler('%s' % ok[host], 5, ' '))
- hostline += ('changed=%s'
- % self._add_filler('%s' % changed[host], 5, ' '))
- hostline += ('unreachable=%s'
- % self._add_filler('%s' % unreachable[host], 5, ' '))
- hostline += 'failed=%s' % failures[host]
+ hostline = '\n%s' % self._add_filler(host, 28, ' ')
+ hostline += (': ok=%s'
+ % self._add_filler('%s' % ok[host], 5, ' '))
+ hostline += ('changed=%s'
+ % self._add_filler('%s' % changed[host], 5, ' '))
+ hostline += ('unreachable=%s'
+ % self._add_filler('%s' % unreachable[host], 5, ' '))
+ hostline += 'failed=%s' % failures[host]
msg += hostline
return msg
def _format_task_end(self, packet):
- host = packet['host']
- status = packet['status']
- msg = '%s: [%s]' % (status, host)
- if status == 'failed' or status == 'unreachable':
- results_dict = packet['results']
- taskname = packet['task']['name']
+ host = packet['host']
+ status = packet['status']
+ msg = '%s: [%s]' % (status, host)
+ if status == 'failed' or status == 'unreachable':
+ results_dict = packet['results']
+ taskname = packet['task']['name']
- # update saved error messages
+ # update saved error messages
self._errors.append(self._format_error(taskname, host,
status, results_dict))
- # format log message
+ # format log message
results = json.dumps(results_dict)
- msg = 'fatal: [%s]: %s! => %s' % (host, status.upper(), results)
+ msg = 'fatal: [%s]: %s! => %s' % (host, status.upper(), results)
return msg
def _format_task_start(self, packet):
- taskname = packet['name']
- task_line = 'TASK [%s] ' % taskname
- msg = '\n' + self._add_filler(task_line, LINE_LENGTH, '*')
+ taskname = packet['name']
+ task_line = 'TASK [%s] ' % taskname
+ msg = '\n' + self._add_filler(task_line, LINE_LENGTH, '*')
return msg
def _format_error(self, taskname, host, status, results):
- # get the primary error message
- err_msg = self._safe_get(results, 'msg')
+ # get the primary error message
+ err_msg = self._safe_get(results, 'msg')
- # there may be more detailed error msgs under results
- sub_results = self._safe_get(results, 'results')
+ # there may be more detailed error msgs under results
+ sub_results = self._safe_get(results, 'results')
if sub_results:
- sub_errs = ''
- comma = ''
+ sub_errs = ''
+ comma = ''
for invocation in sub_results:
- is_failed = invocation.get('failed', False)
+ is_failed = invocation.get('failed', False)
if is_failed is True:
- sub_msg = self._safe_get(invocation, 'msg')
+ sub_msg = self._safe_get(invocation, 'msg')
if not sub_msg:
- sub_msg = self._safe_get(invocation, 'stderr')
+ sub_msg = self._safe_get(invocation, 'stderr')
if not sub_msg:
- self._safe_get(invocation, 'stdout')
- sub_errs = ''.join([sub_errs, comma, sub_msg])
+ self._safe_get(invocation, 'stdout')
+ sub_errs = ''.join([sub_errs, comma, sub_msg])
if sub_msg:
- comma = ', '
+ comma = ', '
if sub_errs:
- err_msg = ''.join([err_msg, ' [', sub_errs, ']'])
+ err_msg = ''.join([err_msg, ' [', sub_errs, ']'])
if not err_msg or not err_msg.strip():
- # sometimes the error message is in std_out
- # eg- "stdout": 'localhost | FAILED! => {"changed": false,
- # "failed": true, "msg": "...msg..."}'
- stdout = self._safe_get(results, 'stdout')
- if '"msg": "' in stdout:
- err_msg = stdout.split('"msg": "')[1]
- err_msg = err_msg.split('"')[0]
+ # sometimes the error message is in std_out
+ # eg- "stdout": 'localhost | FAILED! => {"changed": false,
+ # "failed": true, "msg": "...msg..."}'
+ stdout = self._safe_get(results, 'stdout')
+ if '"msg": "' in stdout:
+ err_msg = stdout.split('"msg": "')[1]
+ err_msg = err_msg.split('"')[0]
if not err_msg:
err_msg = stdout
if not err_msg or not err_msg.strip():
- # if still no err_msg, provide entire result
+ # if still no err_msg, provide entire result
try:
err_msg = json.dumps(results)
except Exception as e:
- LOG.debug('unable to convert results to string' % str(e))
- msg = ('Host: %s, Task: %s, Status: %s, Message: %s' %
+ LOG.debug('unable to convert results to string' % str(e))
+ msg = ('Host: %s, Task: %s, Status: %s, Message: %s' %
(host, taskname, status, err_msg))
return msg
def _safe_get(self, dictionary, key):
"""get value, never return None"""
- val = dictionary.get(key, '')
+ val = dictionary.get(key, '')
if val is None:
- val = ''
+ val = ''
return val
def _add_filler(self, msg, length, filler):
@@ -478,25 +478,25 @@
"""
packets = []
has_fragment = True
- if data.endswith('\n'):
+ if data.endswith('\n'):
has_fragment = False
else:
- LOG.debug('fragment found: %s' % data)
+ LOG.debug('fragment found: %s' % data)
i = 0
- lines = data.split('\n')
+ lines = data.split('\n')
num_lines = len(lines)
for line in lines:
i += 1
if i == 1:
- # first line
+ # first line
line = self._fragment + line
- self._fragment = ''
+ self._fragment = ''
if i == num_lines and has_fragment:
- # last line is incomplete, save as fragment
+ # last line is incomplete, save as fragment
self._fragment = line
break
if not line:
- # ignore empty string lines
+ # ignore empty string lines
continue
info = self.json_load(line)
if info:
@@ -508,7 +508,7 @@
try:
retval = json.loads(string_var)
except Exception as e:
- LOG.error('invalid string for json encoding: %s' % string_var)
+ LOG.error('invalid string for json encoding: %s' % string_var)
if raise_on_err:
raise e
return retval
@@ -545,7 +545,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/ansible/playbook.html b/doc/build/html/_modules/kollacli/common/ansible/playbook.html
index c80e5f7..c29b9a0 100644
--- a/doc/build/html/_modules/kollacli/common/ansible/playbook.html
+++ b/doc/build/html/_modules/kollacli/common/ansible/playbook.html
@@ -6,7 +6,7 @@
- kollacli.common.ansible.playbook — kollacli 3.0.1.dev435 documentation
+ kollacli.common.ansible.playbook — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.ansible.playbook
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import os
import traceback
@@ -80,18 +80,18 @@
[docs]class AnsiblePlaybook(object):
- playbook_path = ''
- extra_vars = ''
+ playbook_path = ''
+ extra_vars = ''
include_passwords = True
flush_cache = True
print_output = True
verbose_level = 0
- hosts = None
- groups = None
- services = None
+ hosts = None # type: List[str]
+ groups = None # type: List[str]
+ services = None # type: List[str]
serial = False
- deploy_id = None
- inventory = None
+ deploy_id = None # type: str
+ inventory = None # type: Inventory
[docs] def run(self):
try:
@@ -101,7 +101,7 @@
cmd = self._get_playbook_cmd(inventory_path)
self._log_ansible_cmd(cmd, inventory_path)
- # create and run the job
+ # create and run the job
job = AnsibleJob(cmd, self.deploy_id,
self.print_output, inventory_path)
job.run()
@@ -113,66 +113,66 @@
def _check_for_plugin(self):
"""check that plug-in is properly installed"""
pi_dir = get_ansible_plugin_dir()
- pi_path = os.path.join(pi_dir, 'kolla_callback.py')
+ pi_path = os.path.join(pi_dir, 'kolla_callback.py')
if not os.path.exists(pi_path):
- LOG.warning(u._('WARNING: kolla callback plug-in is missing. '
- 'Should be here: {path}\n').format(path=pi_path))
+ LOG.warning(u._('WARNING: kolla callback plug-in is missing. '
+ 'Should be here: {path}\n').format(path=pi_path))
else:
ansible_cfg_path = os.path.join(
- get_kolla_home(), '.ansible.cfg')
- with open(ansible_cfg_path, 'r') as cfg:
+ get_kolla_home(), '.ansible.cfg')
+ with open(ansible_cfg_path, 'r') as cfg:
whitelist_ok = False
for line in cfg:
- if (line.startswith('callback_whitelist') and
- 'kolla_callback' in line):
+ if (line.startswith('callback_whitelist') and
+ 'kolla_callback' in line):
whitelist_ok = True
break
if not whitelist_ok:
- LOG.warning(u._('WARNING: kolla callback plug-in is not '
- 'whitelisted '
- 'in {path}\n').format(path=ansible_cfg_path))
+ LOG.warning(u._('WARNING: kolla callback plug-in is not '
+ 'whitelisted '
+ 'in {path}\n').format(path=ansible_cfg_path))
def _get_playbook_cmd(self, inventory_path):
- flag = ''
- # verbose levels: 1=not verbose, 2=more verbose
+ flag = ''
+ # verbose levels: 1=not verbose, 2=more verbose
if self.verbose_level > 1:
- flag = '-vvv'
+ flag = '-vvv'
ansible_cmd = get_ansible_command(playbook=True)
admin_user = get_admin_user()
- cmd = '/usr/bin/sudo -u %s %s %s' % (admin_user, ansible_cmd, flag)
+ cmd = '/usr/bin/sudo -u %s %s %s' % (admin_user, ansible_cmd, flag)
- cmd += ' -i %s' % inventory_path
+ cmd += ' -i %s' % inventory_path
if self.include_passwords:
- cmd += ' %s' % self._get_password_path()
+ cmd += ' %s' % self._get_password_path()
- cmd += ' %s' % self.playbook_path
+ cmd += ' %s' % self.playbook_path
if self.extra_vars or self.serial:
- extra_vars = ''
+ extra_vars = ''
if self.extra_vars:
extra_vars = self.extra_vars
if self.serial:
- extra_vars += ' '
+ extra_vars += ' '
if self.serial:
- extra_vars += 'serial_var=1'
+ extra_vars += 'serial_var=1'
- cmd += ' --extra-vars \"%s\"' % extra_vars
+ cmd += ' --extra-vars \"%s\"' % extra_vars
if self.services:
- service_string = ''
+ service_string = ''
first = True
for service in self.services:
if not first:
- service_string = service_string + ','
+ service_string = service_string + ','
else:
first = False
service_string = service_string + service
- cmd += ' --tags %s' % service_string
+ cmd += ' --tags %s' % service_string
if self.flush_cache:
- cmd += ' --flush-cache'
+ cmd += ' --flush-cache'
return cmd
def _make_temp_inventory(self):
@@ -188,37 +188,37 @@
for hostname in self.hosts:
host = self.inventory.get_host(hostname)
if not host:
- raise NotInInventory(u._('Host'), hostname)
- inventory_filter['deploy_hosts'] = self.hosts
+ raise NotInInventory(u._('Host'), hostname)
+ inventory_filter['deploy_hosts'] = self.hosts
elif self.groups:
for groupname in self.groups:
group = self.inventory.get_group(groupname)
if not group:
- raise NotInInventory(u._('Group'), groupname)
- inventory_filter['deploy_groups'] = self.groups
+ raise NotInInventory(u._('Group'), groupname)
+ inventory_filter['deploy_groups'] = self.groups
inventory_path = \
self.inventory.create_json_gen_file(inventory_filter)
- # inv path = /tmp/kolla_UUID/temp_inventory.py
+ # inv path = /tmp/kolla_UUID/temp_inventory.py
deploy_id = os.path.dirname(inventory_path)
- self.deploy_id = deploy_id.split('kolla_')[1]
+ self.deploy_id = deploy_id.split('kolla_')[1]
return inventory_path
def _get_password_path(self):
kolla_etc = get_kolla_etc()
- return ('-e @' + os.path.join(kolla_etc, 'passwords.yml '))
+ return ('-e @' + os.path.join(kolla_etc, 'passwords.yml '))
def _log_ansible_cmd(self, cmd, inventory_path):
if self.verbose_level > 2:
- # log the ansible command
- LOG.debug('cmd:\n%s' % cmd)
+ # log the ansible command
+ LOG.debug('cmd:\n%s' % cmd)
if self.verbose_level > 3:
- # log the inventory
- with open(inventory_path, 'r') as inv_file:
+ # log the inventory
+ with open(inventory_path, 'r') as inv_file:
inv = inv_file.read()
- LOG.debug('\ninventory: \n%s' % inv)
+ LOG.debug('\ninventory: \n%s' % inv)
@@ -252,7 +252,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/inventory.html b/doc/build/html/_modules/kollacli/common/inventory.html
index 25e3839..cbdb3fd 100644
--- a/doc/build/html/_modules/kollacli/common/inventory.html
+++ b/doc/build/html/_modules/kollacli/common/inventory.html
@@ -6,7 +6,7 @@
- kollacli.common.inventory — kollacli 3.0.1.dev435 documentation
+ kollacli.common.inventory — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.inventory
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy import copy
import json
import jsonpickle
@@ -83,6 +83,7 @@
from kollacli.common.service import Service
from kollacli.common.sshutils import ssh_setup_host
from kollacli.common.subservice import SubService
+from kollacli.common.utils import get_admin_uids
from kollacli.common.utils import get_admin_user
from kollacli.common.utils import get_ansible_command
from kollacli.common.utils import get_group_vars_dir
@@ -92,21 +93,22 @@
from kollacli.common.utils import sync_read_file
from kollacli.common.utils import sync_write_file
-ANSIBLE_SSH_USER = 'ansible_ssh_user'
-ANSIBLE_CONNECTION = 'ansible_connection'
-ANSIBLE_BECOME = 'ansible_become'
+ANSIBLE_SSH_USER = 'ansible_ssh_user'
+ANSIBLE_CONNECTION = 'ansible_connection'
+ANSIBLE_BECOME = 'ansible_become'
-INVENTORY_PATH = 'ansible/inventory.json'
+INVENTORY_PATH = 'ansible/inventory.json'
-COMPUTE_GRP_NAME = 'compute'
+COMPUTE_GRP_NAME = 'compute'
-# these groups cannot be deleted, they are required by kolla
+# these groups cannot be deleted, they are required by kolla
PROTECTED_GROUPS = [COMPUTE_GRP_NAME]
LOG = logging.getLogger(__name__)
[docs]def remove_temp_inventory(path):
+ # type: (str) -> None
"""remove temp inventory file and its parent directory"""
if path:
if os.path.exists(path):
@@ -127,62 +129,62 @@
1: (v2.0.1) initial release
"""
def __init__(self):
- self._groups = {} # kv = name:object
- self._hosts = {} # kv = name:object
- self._services = {} # kv = name:object
- self._sub_services = {} # kv = name:object
+ self._groups = {} # kv = name:object
+ self._hosts = {} # kv = name:object
+ self._services = {} # kv = name:object
+ self._sub_services = {} # kv = name:object
self.vars = {}
self.version = self.__class__.class_version
self.remote_mode = True
- # initialize the inventory to its defaults
+ # initialize the inventory to its defaults
self._create_default_inventory()
[docs] def upgrade(self):
- # check for new services or subservices in the all-in-one file
+ # check for new services or subservices in the all-in-one file
self._upgrade_services()
if self.version <= 1:
- # upgrade from inventory v1
+ # upgrade from inventory v1
- # set ceilometer groups to that of heat
- heat = self.get_service('heat')
- ceilometer = self.get_service('ceilometer')
+ # set ceilometer groups to that of heat
+ heat = self.get_service('heat')
+ ceilometer = self.get_service('ceilometer')
groups = heat.get_groupnames()
for group in groups:
ceilometer.add_groupname(group)
if self.version <= 2:
- # upgrade from inventory v2
+ # upgrade from inventory v2
- # some sub-services may be missing their parent associations.
- # they are now needed in v3.
+ # some sub-services may be missing their parent associations.
+ # they are now needed in v3.
for svc in self.get_services():
for sub_svcname in svc.get_sub_servicenames():
sub_svc = self.get_sub_service(sub_svcname)
if not sub_svc.get_parent_servicename():
sub_svc.set_parent_servicename(svc.name)
- # update the version and save upgraded inventory file
+ # update the version and save upgraded inventory file
self.version = self.__class__.class_version
Inventory.save(self)
def _upgrade_services(self):
allinone = AllInOne()
- # add new services
+ # add new services
for servicename, service in allinone.services.items():
if servicename not in self._services:
self._services[servicename] = service
- # add new subservices
+ # add new subservices
for subservicename, subservice in allinone.sub_services.items():
if subservicename not in self._sub_services:
self._sub_services[subservicename] = subservice
- # remove obsolete subservices
+ # remove obsolete subservices
for subservicename in copy(self._sub_services).keys():
if subservicename not in allinone.sub_services:
self.delete_sub_service(subservicename)
- # remove obsolete services
+ # remove obsolete services
for servicename in copy(self._services).keys():
if servicename not in allinone.services:
self.delete_service(servicename)
@@ -191,46 +193,46 @@
[docs] def load():
"""load the inventory from a pickle file"""
inventory_path = os.path.join(get_kollacli_etc(), INVENTORY_PATH)
- data = ''
+ data = ''
try:
if os.path.exists(inventory_path):
data = sync_read_file(inventory_path)
- # The inventory path changed between v1 and v2. Need to change
- # path throughout the inventory. This has to be done before
- # the pickle decode.
- if 'kollacli.common.inventory' not in data:
+ # The inventory path changed between v1 and v2. Need to change
+ # path throughout the inventory. This has to be done before
+ # the pickle decode.
+ if 'kollacli.common.inventory' not in data:
data = data.replace(
- '"py/object": "kollacli.ansible.inventory.',
- '"py/object": "kollacli.common.inventory.')
+ '"py/object": "kollacli.ansible.inventory.',
+ '"py/object": "kollacli.common.inventory.')
- # The Host, HostGroup, Service and SubService were moved out of
- # inventory and into their own modules
- if 'kollacli.common.service' not in data:
+ # The Host, HostGroup, Service and SubService were moved out of
+ # inventory and into their own modules
+ if 'kollacli.common.service' not in data:
data = data.replace(
- '"py/object": "kollacli.common.inventory.Service"',
- '"py/object": "kollacli.common.service.Service"')
+ '"py/object": "kollacli.common.inventory.Service"',
+ '"py/object": "kollacli.common.service.Service"')
data = data.replace(
- '"py/object": "kollacli.common.inventory.SubService"',
- '"py/object": "kollacli.common.subservice.SubService"')
+ '"py/object": "kollacli.common.inventory.SubService"',
+ '"py/object": "kollacli.common.subservice.SubService"')
data = data.replace(
- '"py/object": "kollacli.common.inventory.Host"',
- '"py/object": "kollacli.common.host.Host"')
+ '"py/object": "kollacli.common.inventory.Host"',
+ '"py/object": "kollacli.common.host.Host"')
data = data.replace(
- '"py/object": "kollacli.common.inventory.HostGroup"',
- '"py/object": "kollacli.common.host_group.HostGroup"')
+ '"py/object": "kollacli.common.inventory.HostGroup"',
+ '"py/object": "kollacli.common.host_group.HostGroup"')
if data.strip():
inventory = jsonpickle.decode(data)
- # upgrade version handling
+ # upgrade version handling
if inventory.version != inventory.class_version:
inventory.upgrade()
else:
inventory = Inventory()
except Exception:
raise FailedOperation(
- u._('Loading inventory failed. : {error}')
+ u._('Loading inventory failed. : {error}')
.format(error=traceback.format_exc()))
return inventory
@@ -239,7 +241,7 @@
"""Save the inventory in a pickle file"""
inventory_path = os.path.join(get_kollacli_etc(), INVENTORY_PATH)
try:
- # multiple trips thru json to render a readable inventory file
+ # multiple trips thru json to render a readable inventory file
data = jsonpickle.encode(inventory)
data_str = json.loads(data)
pretty_data = json.dumps(data_str, indent=4)
@@ -247,7 +249,7 @@
except Exception as e:
raise FailedOperation(
- u._('Saving inventory failed. : {error}')
+ u._('Saving inventory failed. : {error}')
.format(error=str(e)))
[docs] def get_hosts(self):
@@ -269,26 +271,26 @@
if group name is not none, add host to group
"""
if groupname and groupname not in self._groups:
- raise NotInInventory(u._('Group'), groupname)
+ raise NotInInventory(u._('Group'), groupname)
if groupname and hostname not in self._hosts:
- # if a groupname is specified, the host must already exist
- raise NotInInventory(u._('Host'), hostname)
+ # if a groupname is specified, the host must already exist
+ raise NotInInventory(u._('Host'), hostname)
if not groupname and not self.remote_mode and len(self._hosts) >= 1:
raise InvalidConfiguration(
- u._('Cannot have more than one host when in local deploy '
- 'mode.'))
+ u._('Cannot have more than one host when in local deploy '
+ 'mode.'))
changed = False
- # create new host if it doesn't exist
+ # create new host if it doesn't exist
host = Host(hostname)
if hostname not in self.get_hostnames():
- # a new host is being added to the inventory
+ # a new host is being added to the inventory
changed = True
self._hosts[hostname] = host
- # a host is to be added to an existing group
+ # a host is to be added to an existing group
elif groupname:
group = self._groups[groupname]
if hostname not in group.get_hostnames():
@@ -310,7 +312,7 @@
"""
changed = False
if groupname and groupname not in self._groups:
- raise NotInInventory(u._('Group'), groupname)
+ raise NotInInventory(u._('Group'), groupname)
if hostname not in self._hosts:
return changed
@@ -334,6 +336,7 @@
"""setup multiple hosts
hosts_info is a dict of format:
+
{'hostname1': {
'password': password
'uname': user_name
@@ -345,44 +348,50 @@
for hostname, host_info in hosts_info.items():
host = self.get_host(hostname)
if not host:
- failed_hosts[hostname] = u._("Host doesn't exist.")
+ failed_hosts[hostname] = u._("Host doesn't exist.")
continue
- if not host_info or 'password' not in host_info:
- failed_hosts[hostname] = u._('No password in yml file.')
+ if not host_info or 'password' not in host_info:
+ failed_hosts[hostname] = u._('No password in yml file.')
continue
- passwd = host_info['password']
+ passwd = host_info['password']
uname = None
- if 'uname' in host_info:
- uname = host_info['uname']
+ if 'uname' in host_info:
+ uname = host_info['uname']
try:
self.setup_host(hostname, passwd, uname)
except Exception as e:
- failed_hosts[hostname] = '%s' % e
+ failed_hosts[hostname] = '%s' % e
if failed_hosts:
- summary = '\n'
+ summary = '\n'
for hostname, err in failed_hosts.items():
- summary = summary + '- %s: %s\n' % (hostname, err)
+ summary = summary + '- %s: %s\n' % (hostname, err)
raise HostError(
- u._('Not all hosts were set up. : {reasons}')
+ u._('Not all hosts were set up. : {reasons}')
.format(reasons=summary))
else:
- LOG.info(u._LI('All hosts were successfully set up.'))
+ LOG.info(u._LI('All hosts were successfully set up.'))
[docs] def setup_host(self, hostname, password, uname=None):
try:
LOG.info(
- u._LI('Starting setup of host ({host}).')
+ u._LI('Starting setup of host ({host}).')
.format(host=hostname))
- ssh_setup_host(hostname, password, uname)
- check_ok, msg = self.ssh_check_host(hostname)
- if not check_ok:
- raise Exception(u._('Post-setup ssh check failed. {err}')
- .format(err=msg))
- LOG.info(u._LI('Host ({host}) setup succeeded.')
- .format(host=hostname))
+ check_ok, _ = self.ssh_check_host(hostname)
+ if check_ok:
+ LOG.info(u._LI('Host ({host}) is already setup.')
+ .format(host=hostname))
+ else:
+ # host needs setup
+ ssh_setup_host(hostname, password, uname)
+ check_ok, msg = self.ssh_check_host(hostname)
+ if not check_ok:
+ raise Exception(u._('Post-setup ssh check failed. {err}')
+ .format(err=msg))
+ LOG.info(u._LI('Host ({host}) setup succeeded.')
+ .format(host=hostname))
except Exception as e:
raise HostError(
- u._('Host ({host}) setup failed : {error}')
+ u._('Host ({host}) setup failed : {error}')
.format(host=hostname, error=str(e)))
return True
@@ -396,29 +405,29 @@
for hostname in hostnames:
is_ok, msg = self.ssh_check_host(hostname)
summary[hostname] = {}
- summary[hostname]['success'] = is_ok
- summary[hostname]['msg'] = msg
+ summary[hostname]['success'] = is_ok
+ summary[hostname]['msg'] = msg
return summary
[docs] def ssh_check_host(self, hostname):
- err_msg, output = self.run_ansible_command('-m ping', hostname)
+ err_msg, output = self.run_ansible_command('-m ping', hostname)
is_ok = True
if err_msg:
is_ok = False
msg = (
- u._('Host ({host}) ssh check failed. : {error} {message}')
+ u._('Host ({host}) ssh check failed. : {error} {message}')
.format(host=hostname, error=err_msg, message=output))
else:
- msg = (u._LI('Host ({host}) ssh check succeeded.')
+ msg = (u._LI('Host ({host}) ssh check succeeded.')
.format(host=hostname))
return is_ok, msg
[docs] def run_ansible_command(self, ansible_command, hostname):
err_msg = None
- command_string = '/usr/bin/sudo -u %s %s -vvv' % \
+ command_string = '/usr/bin/sudo -u %s %s -vvv' % \
(get_admin_user(), get_ansible_command())
gen_file_path = self.create_json_gen_file()
- cmd = '%s %s -i %s %s' % (command_string, hostname, gen_file_path,
+ cmd = '%s %s -i %s %s' % (command_string, hostname, gen_file_path,
ansible_command)
try:
err_msg, output = run_cmd(cmd, False)
@@ -430,11 +439,11 @@
[docs] def add_group(self, groupname):
- # Group names cannot overlap with service names:
+ # Group names cannot overlap with service names:
if groupname in self._services or groupname in self._sub_services:
raise InvalidArgument(
- u._('Invalid group name. A service name '
- 'cannot be used for a group name.'))
+ u._('Invalid group name. A service name '
+ 'cannot be used for a group name.'))
if groupname not in self._groups:
self._groups[groupname] = HostGroup(groupname)
@@ -448,10 +457,10 @@
[docs] def remove_group(self, groupname):
if groupname in PROTECTED_GROUPS:
raise InvalidArgument(
- u._('Cannot remove {group} group. It is required by kolla.')
+ u._('Cannot remove {group} group. It is required by kolla.')
.format(group=groupname))
- # remove group from services & subservices
+ # remove group from services & subservices
for service in self._services.values():
service.remove_groupname(groupname)
@@ -459,7 +468,7 @@
subservice.remove_groupname(groupname)
group_vars = os.path.join(get_group_vars_dir(), groupname)
- if os.path.exists(group_vars) and groupname != '__GLOBAL__':
+ if os.path.exists(group_vars) and groupname != '__GLOBAL__':
os.remove(group_vars)
if groupname in self._groups:
@@ -552,7 +561,7 @@
[docs] def add_group_to_service(self, groupname, servicename):
if groupname not in self._groups:
- raise NotInInventory(u._('Group'), groupname)
+ raise NotInInventory(u._('Group'), groupname)
if servicename in self._services:
service = self.get_service(servicename)
service.add_groupname(groupname)
@@ -560,11 +569,11 @@
sub_service = self.get_sub_service(servicename)
sub_service.add_groupname(groupname)
else:
- raise NotInInventory(u._('Service'), servicename)
+ raise NotInInventory(u._('Service'), servicename)
[docs] def remove_group_from_service(self, groupname, servicename):
if groupname not in self._groups:
- raise NotInInventory(u._('Group'), groupname)
+ raise NotInInventory(u._('Group'), groupname)
if servicename in self._services:
service = self.get_service(servicename)
service.remove_groupname(groupname)
@@ -572,7 +581,7 @@
sub_service = self.get_sub_service(servicename)
sub_service.remove_groupname(groupname)
else:
- raise NotInInventory(u._('Service'), servicename)
+ raise NotInInventory(u._('Service'), servicename)
[docs] def create_sub_service(self, sub_servicename):
if sub_servicename not in self._sub_services:
@@ -612,7 +621,7 @@
[docs] def set_deploy_mode(self, remote_flag):
if not remote_flag and len(self._hosts) > 1:
raise InvalidConfiguration(
- u._('Cannot set local deploy mode when multiple hosts exist.'))
+ u._('Cannot set local deploy mode when multiple hosts exist.'))
self.remote_mode = remote_flag
for group in self.get_groups():
@@ -654,58 +663,58 @@
"""
jdict = {}
- # if no filter provided, use all groups, all hosts
+ # if no filter provided, use all groups, all hosts
deploy_hostnames = self.get_hostnames()
deploy_groupnames = self.get_groupnames()
if inventory_filter:
- if 'deploy_hosts' in inventory_filter:
- deploy_hostnames = inventory_filter['deploy_hosts']
- if 'deploy_groups' in inventory_filter:
- deploy_groupnames = inventory_filter['deploy_groups']
+ if 'deploy_hosts' in inventory_filter:
+ deploy_hostnames = inventory_filter['deploy_hosts']
+ if 'deploy_groups' in inventory_filter:
+ deploy_groupnames = inventory_filter['deploy_groups']
- # add hostgroups
+ # add hostgroups
for group in self.get_groups():
jdict[group.name] = {}
- jdict[group.name]['hosts'] = []
+ jdict[group.name]['hosts'] = []
if group.name in deploy_groupnames:
- jdict[group.name]['hosts'] = \
+ jdict[group.name]['hosts'] = \
self._filter_hosts(group.get_hostnames(), deploy_hostnames)
- jdict[group.name]['children'] = []
- jdict[group.name]['vars'] = group.get_vars()
+ jdict[group.name]['children'] = []
+ jdict[group.name]['vars'] = group.get_vars()
- # add top-level services and what groups they are in
+ # add top-level services and what groups they are in
for service in self.get_services():
jdict[service.name] = {}
- jdict[service.name]['children'] = service.get_groupnames()
+ jdict[service.name]['children'] = service.get_groupnames()
- # add sub-services and their groups
+ # add sub-services and their groups
for sub_svc in self.get_sub_services():
jdict[sub_svc.name] = {}
groupnames = sub_svc.get_groupnames()
if groupnames:
- # sub-service is associated with a group(s)
- jdict[sub_svc.name]['children'] = groupnames
+ # sub-service is associated with a group(s)
+ jdict[sub_svc.name]['children'] = groupnames
else:
- # sub-service is associated with parent service
- jdict[sub_svc.name]['children'] = \
+ # sub-service is associated with parent service
+ jdict[sub_svc.name]['children'] = \
[sub_svc.get_parent_servicename()]
- # temporarily create group containing all hosts. this is needed for
- # ansible commands that are performed on hosts not yet in groups.
- group = self.add_group('__GLOBAL__')
+ # temporarily create group containing all hosts. this is needed for
+ # ansible commands that are performed on hosts not yet in groups.
+ group = self.add_group('__GLOBAL__')
jdict[group.name] = {}
- jdict[group.name]['hosts'] = deploy_hostnames
- jdict[group.name]['vars'] = group.get_vars()
+ jdict[group.name]['hosts'] = deploy_hostnames
+ jdict[group.name]['vars'] = group.get_vars()
self.remove_group(group.name)
- # process hosts vars
- jdict['_meta'] = {}
- jdict['_meta']['hostvars'] = {}
+ # process hosts vars
+ jdict['_meta'] = {}
+ jdict['_meta']['hostvars'] = {}
for hostname in deploy_hostnames:
host = self.get_host(hostname)
if host:
- jdict['_meta']['hostvars'][hostname] = host.get_vars()
+ jdict['_meta']['hostvars'][hostname] = host.get_vars()
return json.dumps(jdict)
def _filter_hosts(self, initial_hostnames, deploy_hostnames):
@@ -731,19 +740,21 @@
json_out = self.get_ansible_json(inventory_filter)
deploy_id = str(uuid.uuid4())
- dirname = 'kolla_%s' % deploy_id
+ dirname = 'kolla_%s' % deploy_id
dirpath = os.path.join(tempfile.gettempdir(), dirname)
- os.mkdir(dirpath)
- json_gen_path = os.path.join(dirpath, 'temp_inventory.py')
+ os.mkdir(dirpath, 0o775)
+ _, gid = get_admin_uids()
+ os.chown(dirpath, -1, gid) # nosec
+ json_gen_path = os.path.join(dirpath, 'temp_inventory.py')
- with open(json_gen_path, 'w') as json_gen_file:
- json_gen_file.write('#!/usr/bin/env python\n')
- # the quotes here are significant. The json_out has double quotes
- # embedded in it so single quotes are needed to wrap it.
- json_gen_file.write("print('%s')" % json_out)
+ with open(json_gen_path, 'w') as json_gen_file:
+ json_gen_file.write('#!/usr/bin/env python\n')
+ # the quotes here are significant. The json_out has double quotes
+ # embedded in it so single quotes are needed to wrap it.
+ json_gen_file.write("print('%s')" % json_out)
- # set executable by group
- os.chmod(json_gen_path, 0o555) # nosec
+ # set executable by group
+ os.chmod(json_gen_path, 0o555) # nosec
return json_gen_path
[docs] def validate_hostnames(self, hostnames):
if not hostnames:
- raise MissingArgument(u._('Host name(s)'))
+ raise MissingArgument(u._('Host name(s)'))
invalid_hosts = []
for hostname in hostnames:
if hostname not in self._hosts:
invalid_hosts.append(hostname)
if invalid_hosts:
- raise NotInInventory(u._('Host'), invalid_hosts)
+ raise NotInInventory(u._('Host'), invalid_hosts)
[docs] def validate_groupnames(self, groupnames):
if not groupnames:
- raise MissingArgument(u._('Group name(s)'))
+ raise MissingArgument(u._('Group name(s)'))
invalid_groups = []
for groupname in groupnames:
if groupname not in self._groups:
invalid_groups.append(groupname)
if invalid_groups:
- raise NotInInventory(u._('Group'), invalid_groups)
+ raise NotInInventory(u._('Group'), invalid_groups)
[docs] def validate_servicenames(self, servicenames):
if not servicenames:
- raise MissingArgument(u._('Service name(s)'))
+ raise MissingArgument(u._('Service name(s)'))
invalid_services = []
for servicename in servicenames:
if (servicename not in self._services and
servicename not in self._sub_services):
invalid_services.append(servicename)
if invalid_services:
- raise NotInInventory(u._('Service'), invalid_services)
+ raise NotInInventory(u._('Service'), invalid_services)
def _create_default_inventory(self):
allin1 = AllInOne()
@@ -821,7 +832,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/passwords.html b/doc/build/html/_modules/kollacli/common/passwords.html
index 0ab2010..8b83cdf 100644
--- a/doc/build/html/_modules/kollacli/common/passwords.html
+++ b/doc/build/html/_modules/kollacli/common/passwords.html
@@ -6,7 +6,7 @@
- kollacli.common.passwords — kollacli 3.0.1.dev435 documentation
+ kollacli.common.passwords — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.passwords
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 kollacli.i18n as u
@@ -67,7 +67,7 @@
from kollacli.api.exceptions import FailedOperation
from kollacli.common import utils
-PWDS_FILENAME = 'passwords.yml'
+PWDS_FILENAME = 'passwords.yml'
[docs]def set_password(pwd_key, pwd_value):
@@ -76,11 +76,21 @@
If the password name exists, it will be changed.
If it doesn't exist, a new password will be added.
"""
- cmd = '%s -k %s -v %s' % (_get_cmd_prefix(), pwd_key, pwd_value)
+ cmd = '%s -k %s -v %s' % (_get_cmd_prefix(), pwd_key, pwd_value)
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
raise FailedOperation(
- u._('Password set failed. {error} {message}')
+ u._('Password set failed. {error} {message}')
+ .format(error=err_msg, message=output))
+
+
+[docs]def set_password_sshkey(pwd_key, private_key, public_key):
+ cmd = '%s -k %s -r "%s" -u "%s"' % (_get_cmd_prefix(), pwd_key,
+ private_key, public_key)
+ err_msg, output = utils.run_cmd(cmd, print_output=False)
+ if err_msg:
+ raise FailedOperation(
+ u._('Password ssh key set failed. {error} {message}')
.format(error=err_msg, message=output))
@@ -89,31 +99,54 @@
if the password exists, it will be removed from the passwords file
"""
- cmd = '%s -k %s -c' % (_get_cmd_prefix(), pwd_key)
+ cmd = '%s -k %s -c' % (_get_cmd_prefix(), pwd_key)
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
- raise FailedOperation('%s %s' % (err_msg, output))
+ raise FailedOperation('%s %s' % (err_msg, output))
[docs]def get_password_names():
"""return a list of password names"""
- cmd = '%s -l' % (_get_cmd_prefix())
+ cmd = '%s -l' % (_get_cmd_prefix())
err_msg, output = utils.run_cmd(cmd, print_output=False)
if err_msg:
- raise FailedOperation('%s %s' % (err_msg, output))
+ raise FailedOperation('%s %s' % (err_msg, output))
pwd_names = []
- if output and ',' in output:
- pwd_names = output.strip().split(',')
+ if output and ',' in output:
+ pwd_names = output.strip().split(',')
return pwd_names
+
+[docs]def get_empty_password_values():
+ cmd = '%s -e' % (_get_cmd_prefix())
+ err_msg, output = utils.run_cmd(cmd, print_output=False)
+ # output of this command is a comma separated string of password keys
+ # that have empty values.
+ if err_msg:
+ raise FailedOperation('%s %s' % (err_msg, output))
+
+ empty_keys = []
+ if output:
+ # password keys exist that have no values
+ empty_keys = output.strip().split(',')
+ return empty_keys
+
+
+[docs]def init_passwords():
+ # init empty passwords & ssh keys to auto-gen'd values
+ cmd = '%s -i' % (_get_cmd_prefix())
+ err_msg, output = utils.run_cmd(cmd, print_output=False)
+ if err_msg:
+ raise FailedOperation('%s %s' % (err_msg, output))
+
def _get_cmd_prefix():
actions_path = utils.get_kolla_actions_path()
pwd_file_path = os.path.join(utils.get_kolla_etc(),
PWDS_FILENAME)
user = utils.get_admin_user()
- prefix = ('/usr/bin/sudo -u %s %s password -p %s '
+ prefix = ('/usr/bin/sudo -u %s %s password -p %s '
% (user, actions_path, pwd_file_path))
return prefix
@@ -149,7 +182,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/properties.html b/doc/build/html/_modules/kollacli/common/properties.html
index 2196a2b..ea3c81b 100644
--- a/doc/build/html/_modules/kollacli/common/properties.html
+++ b/doc/build/html/_modules/kollacli/common/properties.html
@@ -6,7 +6,7 @@
- kollacli.common.properties — kollacli 3.0.1.dev435 documentation
+ kollacli.common.properties — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.properties
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy
import logging
import os
@@ -78,10 +78,10 @@
LOG = logging.getLogger(__name__)
-ALLVARS_PATH = 'ansible/group_vars/all.yml'
-GLOBALS_PATH = 'ansible/group_vars/__GLOBAL__'
-ANSIBLE_ROLES_PATH = 'ansible/roles'
-ANSIBLE_DEFAULTS_PATH = 'defaults/main.yml'
+ALLVARS_PATH = 'ansible/group_vars/all.yml'
+GLOBALS_PATH = 'ansible/group_vars/__GLOBAL__'
+ANSIBLE_ROLES_PATH = 'ansible/roles'
+ANSIBLE_DEFAULTS_PATH = 'defaults/main.yml'
[docs]class AnsibleProperties(object):
@@ -126,7 +126,7 @@
if os.path.isfile(file_name):
with open(file_name) as service_file:
service_contents = yaml.safe_load(service_file)
- prop_file_name = service_name + ':main.yml'
+ prop_file_name = service_name + ':main.yml'
for key, value in service_contents.items():
ansible_prop = AnsibleProperty(key, value,
prop_file_name)
@@ -144,7 +144,7 @@
overrides = True
orig_value = self.unique_global_props[key].value
ansible_prop = AnsibleProperty(key, value,
- 'group_vars/all.yml',
+ 'group_vars/all.yml',
overrides, orig_value)
self.global_props.append(ansible_prop)
self.unique_global_props[key] = ansible_prop
@@ -163,7 +163,7 @@
override_flags.ovr_global = True
orig_value = self.unique_global_props[key].value
ansible_prop = AnsibleProperty(key, value,
- 'group_vars/__GLOBAL',
+ 'group_vars/__GLOBAL',
overrides, orig_value)
ansible_prop.override_flags = override_flags
self.global_props.append(ansible_prop)
@@ -175,7 +175,7 @@
hostnames = self._inventory.get_hostnames()
for hostfile in os.listdir(host_dir):
if hostfile not in hostnames:
- # skip any host files that don't match existing hosts
+ # skip any host files that don't match existing hosts
continue
self.host_props[hostfile] = []
with open(os.path.join(host_dir, hostfile)) as host_data:
@@ -197,7 +197,7 @@
ansible_prop = AnsibleProperty(key, value,
hostfile,
overrides, orig_value,
- 'host', hostfile)
+ 'host', hostfile)
props.append(ansible_prop)
self.host_props[hostfile] = props
@@ -206,7 +206,7 @@
groupnames = self._inventory.get_groupnames()
for groupfile in os.listdir(group_dir):
if groupfile not in groupnames:
- # skip any files that don't match existing groups
+ # skip any files that don't match existing groups
continue
with open(os.path.join(group_dir, groupfile)) as group_data:
group_contents = yaml.safe_load(group_data)
@@ -227,13 +227,13 @@
ansible_prop = AnsibleProperty(key, value,
groupfile,
overrides, orig_value,
- 'group', groupfile)
+ 'group', groupfile)
props.append(ansible_prop)
self.group_props[groupfile] = props
def _load_inventory(self):
if not self._inventory:
- self._inventory = Inventory.load() # nosec
+ self._inventory = Inventory.load() # nosec
[docs] def get_host_list(self, host_list):
self._load_properties()
@@ -242,7 +242,7 @@
for host_name in host_list:
host = self._inventory.get_host(host_name)
if host is None:
- raise NotInInventory(u._('Host'), host_name)
+ raise NotInInventory(u._('Host'), host_name)
if host_name in self.host_props:
prop_list += self.host_props[host_name]
else:
@@ -259,7 +259,7 @@
for group_name in group_list:
group = self._inventory.get_group(group_name)
if group is None:
- raise NotInInventory(u._('Group'), group_name)
+ raise NotInInventory(u._('Group'), group_name)
if group_name in self.group_props:
prop_list += self.group_props[group_name]
else:
@@ -288,30 +288,27 @@
self._load_properties()
return self.unique_override_flags
- # TODO(bmace) -- if this isn't used for 2.1.x it should be removed
- # property listing is still being tweaked so leaving for
- # the time being in case we want to use it
+ # TODO(bmace) -- if this isn't used for 2.1.x it should be removed
+ # property listing is still being tweaked so leaving for
+ # the time being in case we want to use it
[docs] def filter_jinja2(self, contents):
new_contents = {}
for key, value in contents.items():
if not isinstance(value, six.string_types):
- LOG.debug('removing non-string: %s', value)
+ LOG.debug('removing non-string: %s', value)
continue
- if value and '{{' in value and '}}' in value:
- LOG.debug('removing jinja2 value: %s', value)
+ if value and '{{' in value and '}}' in value:
+ LOG.debug('removing jinja2 value: %s', value)
continue
new_contents[key] = value
return new_contents
[docs] def set_property(self, property_dict):
- try:
- change_property(self.globals_path, property_dict,
- clear=False)
- except Exception as e:
- raise e
+ change_property(self.globals_path, property_dict,
+ clear=False)
[docs] def set_host_property(self, property_dict, hosts):
- # if hosts is None set the property on all hosts
+ # if hosts is None set the property on all hosts
self._load_inventory()
host_list = []
if hosts is None:
@@ -320,7 +317,7 @@
for host_name in hosts:
host = self._inventory.get_host(host_name)
if host is None:
- raise NotInInventory(u._('Host'), host_name)
+ raise NotInInventory(u._('Host'), host_name)
host_list.append(host)
try:
for host in host_list:
@@ -331,7 +328,7 @@
raise e
[docs] def set_group_property(self, property_dict, groups):
- # if groups is None set the property on all hosts
+ # if groups is None set the property on all hosts
self._load_inventory()
group_list = []
if groups is None:
@@ -340,7 +337,7 @@
for group_name in groups:
group = self._inventory.get_group(group_name)
if group is None:
- raise NotInInventory(u._('Group'), group_name)
+ raise NotInInventory(u._('Group'), group_name)
group_list.append(group)
try:
for group in group_list:
@@ -360,7 +357,7 @@
raise e
[docs] def clear_host_property(self, property_list, hosts):
- # if hosts is None set the property on all hosts
+ # if hosts is None set the property on all hosts
self._load_inventory()
host_list = []
if hosts is None:
@@ -369,7 +366,7 @@
for host_name in hosts:
host = self._inventory.get_host(host_name)
if host is None:
- raise NotInInventory(u._('Host'), host_name)
+ raise NotInInventory(u._('Host'), host_name)
host_list.append(host)
try:
for host in host_list:
@@ -380,7 +377,7 @@
raise e
[docs] def clear_group_property(self, property_list, groups):
- # if hosts is None set the property on all hosts
+ # if hosts is None set the property on all hosts
self._load_inventory()
group_list = []
if groups is None:
@@ -389,7 +386,7 @@
for group_name in groups:
group = self._inventory.get_group(group_name)
if group is None:
- raise NotInInventory(u._('Group'), group_name)
+ raise NotInInventory(u._('Group'), group_name)
group_list.append(group)
try:
for group in group_list:
@@ -402,14 +399,14 @@
def _list_to_dict(self, property_list):
property_dict = {}
for key in property_list:
- property_dict[key] = ''
+ property_dict[key] = ''
return property_dict
[docs]class AnsibleProperty(object):
def __init__(self, name, value, file_name, overrides=False,
- orig_value=None, prop_type='global', target=None):
+ orig_value=None, prop_type='global', target=None):
self.name = name
self.value = value
self.prop_type = prop_type
@@ -458,7 +455,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/sshutils.html b/doc/build/html/_modules/kollacli/common/sshutils.html
index 7262d58..2f00b8c 100644
--- a/doc/build/html/_modules/kollacli/common/sshutils.html
+++ b/doc/build/html/_modules/kollacli/common/sshutils.html
@@ -6,7 +6,7 @@
- kollacli.common.sshutils — kollacli 3.0.1.dev435 documentation
+ kollacli.common.sshutils — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.sshutils
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import os.path
import paramiko
@@ -72,7 +72,7 @@
import kollacli.i18n as u
-MIN_DOCKER_VERSION = '1.8.1'
+MIN_DOCKER_VERSION = '1.8.1'
LOG = logging.getLogger(__name__)
@@ -99,17 +99,17 @@
try:
ssh_client = ssh_connect(net_addr, setup_user, password)
- # before modifying the host, check that it meets requirements
- # TODO(bmace) pre / post checks should be done with ansible
+ # before modifying the host, check that it meets requirements
+ # TODO(bmace) pre / post checks should be done with ansible
- # populate authorized keys file w/ public key
- key_dir = os.path.join(os.path.expanduser('~kolla'),
- '.ssh', 'authorized_keys')
- cmd = ('/usr/bin/sudo su - %s -c "echo \'%s\' >> %s"'
+ # populate authorized keys file w/ public key
+ key_dir = os.path.join(os.path.expanduser('~kolla'),
+ '.ssh', 'authorized_keys')
+ cmd = ('/usr/bin/sudo su - %s -c "echo \'%s\' >> %s"'
% (admin_user, public_key, key_dir))
_exec_ssh_cmd(cmd, ssh_client)
- # TODO(bmace) verify ssh connection to the new account
+ # TODO(bmace) verify ssh connection to the new account
except Exception as e:
raise e
finally:
@@ -120,29 +120,28 @@
if ssh_client:
try:
ssh_client.close()
- except Exception: # nosec
+ except Exception: # nosec
pass
def _exec_ssh_cmd(cmd, ssh_client):
LOG.debug(cmd)
- _, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True) # nosec
+ _, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True) # nosec
msg = stdout.read()
errmsg = stderr.read()
- LOG.debug('%s : %s' % (msg, errmsg))
+ LOG.debug('%s : %s' % (msg, errmsg))
if errmsg:
LOG.warn(
- u._LW('WARNING: command : {command})\nmessage : {message}')
+ u._LW('WARNING: command : {command})\nmessage : {message}')
.format(command=cmd, message=errmsg.strip()))
return msg, errmsg
[docs]def ssh_get_public_key():
- keyfile_path = os.path.join(get_kollacli_etc(), 'id_rsa.pub')
- with open(keyfile_path, "r") as public_key_file:
+ keyfile_path = os.path.join(get_kollacli_etc(), 'id_rsa.pub')
+ with open(keyfile_path, "r") as public_key_file:
public_key = public_key_file.read()
- return public_key
- return None
+ return public_key
@@ -176,7 +175,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/support.html b/doc/build/html/_modules/kollacli/common/support.html
index 233b210..7a7fe66 100644
--- a/doc/build/html/_modules/kollacli/common/support.html
+++ b/doc/build/html/_modules/kollacli/common/support.html
@@ -6,7 +6,7 @@
- kollacli.common.support — kollacli 3.0.1.dev435 documentation
+ kollacli.common.support — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.support
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 logging
import os
import tarfile
@@ -68,7 +68,6 @@
from kollacli.api.exceptions import FailedOperation
from kollacli.common.inventory import Inventory
from kollacli.common.properties import AnsibleProperties
-from kollacli.common.utils import get_kolla_etc
from kollacli.common.utils import get_kolla_home
from kollacli.common.utils import get_kolla_log_dir
from kollacli.common.utils import get_kollacli_etc
@@ -83,49 +82,49 @@
self.hostname = hostname
self.inventory = inventory
self.servicenames = servicenames
- self.container_info = {} # container_id: container_img_name
+ self.container_info = {} # container_id: container_img_name
self.filtered_servicenames = {}
[docs] def load_container_info(self):
"""get the list of containers on the host"""
hostname = self.hostname
err_msg, output = \
- self.inventory.run_ansible_command('-a "docker ps -a"', hostname)
+ self.inventory.run_ansible_command('-a "docker ps -a"', hostname)
if err_msg:
- msg = 'Error accessing host %s : %s %s' % (hostname, err_msg,
+ msg = 'Error accessing host %s : %s %s' % (hostname, err_msg,
output)
raise FailedOperation(msg)
if not output:
- msg = ('Host %s is not accessible.' % hostname)
+ msg = ('Host %s is not accessible.' % hostname)
raise FailedOperation(msg)
else:
- if '>>' not in output:
- msg = ('Host: %s. Invalid ansible return data: [%s].'
+ if '>>' not in output:
+ msg = ('Host: %s. Invalid ansible return data: [%s].'
% (hostname, output))
raise FailedOperation(msg)
- if 'NAMES' not in output:
- msg = ('Host: %s. Invalid docker ps return data: [%s].'
+ if 'NAMES' not in output:
+ msg = ('Host: %s. Invalid docker ps return data: [%s].'
% (hostname, output))
raise FailedOperation(msg)
ansible_properties = AnsibleProperties()
base_distro = \
- ansible_properties.get_property('kolla_base_distro')
+ ansible_properties.get_property('kolla_base_distro')
install_type = \
- ansible_properties.get_property('kolla_install_type')
- # typically this prefix will be "ol-openstack-"
- container_prefix = base_distro + '-' + install_type + '-'
+ ansible_properties.get_property('kolla_install_type')
+ # typically this prefix will be "ol-openstack-"
+ container_prefix = base_distro + '-' + install_type + '-'
- # process ps output
+ # process ps output
containers = {}
- # the ps output is after the '>>'
- output = output.split('>>', 1)[1]
- LOG.info('docker ps -a on host: %s:\n%s' % (hostname, output))
+ # the ps output is after the '>>'
+ output = output.split('>>', 1)[1]
+ LOG.info('docker ps -a on host: %s:\n%s' % (hostname, output))
- lines = output.split('\n')
+ lines = output.split('\n')
for line in lines:
tokens = line.split()
if len(tokens) < 2:
@@ -133,32 +132,32 @@
cid = tokens[0]
image = tokens[1]
if container_prefix not in image:
- # skip non-kolla containers
+ # skip non-kolla containers
continue
name = image.split(container_prefix)[1]
- name = name.split(':')[0]
+ name = name.split(':')[0]
containers[cid] = name
self.container_info = containers
[docs] def get_log(self, container_id):
"""read the container log"""
hostname = self.hostname
- cmd = '-a "docker logs %s"' % container_id
+ cmd = '-a "docker logs %s"' % container_id
err_msg, output = self.inventory.run_ansible_command(cmd, hostname)
if err_msg:
- msg = 'Error accessing host %s : %s ' % (hostname, err_msg)
+ msg = 'Error accessing host %s : %s ' % (hostname, err_msg)
raise FailedOperation(msg)
if not output:
- msg = ('Host %s is not accessible.' % hostname)
+ msg = ('Host %s is not accessible.' % hostname)
raise FailedOperation(msg)
- if '>>' not in output:
- msg = ('Host: %s. Invalid ansible return data: [%s].'
+ if '>>' not in output:
+ msg = ('Host: %s. Invalid ansible return data: [%s].'
% (hostname, output))
raise FailedOperation(msg)
- # the log info is after the '>>'
- output = output.split('>>', 1)[1]
+ # the log info is after the '>>'
+ output = output.split('>>', 1)[1]
return output
[docs] def write_logs(self, dirname):
@@ -166,10 +165,10 @@
for container_id, container_name in self.filtered_services.items():
logdata = self.get_log(container_id)
if logdata:
- logname = '%s_%s.log' % (container_name, container_id)
+ logname = '%s_%s.log' % (container_name, container_id)
self.write_logfile(dirname, logname, logdata)
else:
- LOG.warn('No log data found for service %s on host %s'
+ LOG.warn('No log data found for service %s on host %s'
% (container_name, self.hostname))
[docs] def write_logfile(self, dirpath, logname, logdata):
@@ -178,7 +177,7 @@
if not os.path.exists(hostdir):
os.mkdir(hostdir)
fpath = os.path.join(hostdir, logname)
- with open(fpath, 'w') as logfile:
+ with open(fpath, 'w') as logfile:
logfile.write(logdata)
[docs] def filter_services(self):
@@ -187,7 +186,7 @@
for host_svcid, host_svcname in self.container_info.items():
for servicename in self.servicenames:
if (host_svcname == servicename or
- host_svcname.startswith(servicename + '-')):
+ host_svcname.startswith(servicename + '-')):
services_subset[host_svcid] = host_svcname
self.filtered_services = services_subset
@@ -212,70 +211,63 @@
"""
kolla_home = get_kolla_home()
kolla_logs = get_kolla_log_dir()
- kolla_ansible = os.path.join(kolla_home, 'ansible')
- kolla_docs = os.path.join(kolla_home, 'docs')
- kolla_etc = get_kolla_etc()
- kolla_config = os.path.join(kolla_etc, 'config')
- kollacli_etc = get_kollacli_etc().rstrip('/')
- ketc = 'kolla/etc/'
- kshare = 'kolla/share/'
- fd, dump_path = tempfile.mkstemp(dir=dirpath, prefix='kollacli_dump_',
- suffix='.tgz')
- os.close(fd) # avoid fd leak
- with tarfile.open(dump_path, 'w:gz') as tar:
- # Can't blanket add kolla_home because the .ssh dir is
- # accessible by the kolla user only (not kolla group)
+ kolla_ansible = os.path.join(kolla_home, 'ansible')
+ kollacli_etc = get_kollacli_etc().rstrip('/')
+ ketc = 'kolla/etc/'
+ kshare = 'kolla/share/'
+ fd, dump_path = tempfile.mkstemp(dir=dirpath, prefix='kollacli_dump_',
+ suffix='.tgz')
+ os.close(fd) # avoid fd leak
+ with tarfile.open(dump_path, 'w:gz') as tar:
+ # Can't blanket add kolla_home because the .ssh dir is
+ # accessible by the kolla user only (not kolla group)
tar.add(kolla_ansible,
arcname=kshare + os.path.basename(kolla_ansible))
- tar.add(kolla_docs,
- arcname=kshare + os.path.basename(kolla_docs))
- # Can't blanket add kolla_etc because the passwords.yml
- # file is accessible by the kolla user only (not kolla group)
- tar.add(kolla_config,
- arcname=ketc + os.path.basename(kolla_config))
+ # Can't blanket add kolla_etc because the passwords.yml
+ # file is accessible by the kolla user only (not kolla group)
tar.add(kollacli_etc,
arcname=ketc + os.path.basename(kollacli_etc))
- # add kolla log files
+ # add kolla log files
if os.path.isdir(kolla_logs):
tar.add(kolla_logs)
- # add output of various commands
+ # add output of various commands
_add_cmd_info(tar)
return dump_path
def _add_cmd_info(tar):
- # run all the kollacli list commands
- cmds = ['kollacli --version',
- 'kollacli service listgroups',
- 'kollacli service list',
- 'kollacli group listservices',
- 'kollacli group listhosts',
- 'kollacli host list',
- 'kollacli property list',
- 'kollacli password list']
+ # run all the kollacli list commands
+ cmds = ['kollacli --version',
+ 'kollacli service listgroups',
+ 'kollacli service list',
+ 'kollacli group listservices',
+ 'kollacli group listhosts',
+ 'kollacli host list',
+ 'kollacli property list',
+ 'kollacli password list']
- # collect the json inventory output
+ # collect the json inventory output
inventory = Inventory.load()
inv_path = inventory.create_json_gen_file()
cmds.append(inv_path)
try:
- fd, path = tempfile.mkstemp(suffix='.tmp')
+ fd, path = tempfile.mkstemp(suffix='.tmp')
os.close(fd)
- with open(path, 'w') as tmp_file:
+ with open(path, 'w') as tmp_file:
for cmd in cmds:
err_msg, output = run_cmd(cmd, False)
- tmp_file.write('\n\n$ %s\n' % cmd)
+ tmp_file.write('\n\n$ %s\n' % cmd)
if err_msg:
- tmp_file.write('Error message: %s\n' % err_msg)
+ tmp_file.write('Error message: %s\n' % err_msg)
for line in output:
- tmp_file.write(line + '\n')
+ tmp_file.write(line + '\n')
- tar.add(path, arcname=os.path.join('kolla', 'cmds_output'))
+ tar.add(path, arcname=os.path.join('kolla', 'cmds_output'))
except Exception as e:
raise e
finally:
@@ -316,7 +308,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/common/utils.html b/doc/build/html/_modules/kollacli/common/utils.html
index aebbe4c..ba38133 100644
--- a/doc/build/html/_modules/kollacli/common/utils.html
+++ b/doc/build/html/_modules/kollacli/common/utils.html
@@ -6,7 +6,7 @@
- kollacli.common.utils — kollacli 3.0.1.dev435 documentation
+ kollacli.common.utils — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.common.utils
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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 copy
import fcntl
import grp
@@ -67,9 +67,10 @@
import os
import pwd
import six
-import subprocess # nosec
+import subprocess # nosec
import sys
import time
+import yaml
import kollacli.i18n as u
@@ -80,8 +81,8 @@
[docs]def get_log_level():
- evar = os.environ.get('KOLLA_LOG_LEVEL', 'info')
- if evar.lower() == 'debug':
+ evar = os.environ.get('KOLLA_LOG_LEVEL', 'info')
+ if evar.lower() == 'debug':
level = logging.DEBUG
else:
level = logging.INFO
@@ -89,49 +90,49 @@
[docs]def get_ansible_plugin_dir():
- return os.environ.get("ANSIBLE_PLUGINS",
- "/usr/share/ansible/plugins/callback/")
+ return os.environ.get("ANSIBLE_PLUGINS",
+ "/usr/share/ansible/plugins/callback/")
[docs]def get_ansible_etc():
- return os.environ.get("ANSIBLE_ETC",
- "/etc/ansible/")
+ return os.environ.get("ANSIBLE_ETC",
+ "/etc/ansible/")
[docs]def get_kolla_home():
- return os.environ.get("KOLLA_HOME", "/usr/share/kolla/")
+ return os.environ.get("KOLLA_HOME", "/usr/share/kolla/")
[docs]def get_kolla_etc():
- return os.environ.get("KOLLA_ETC", "/etc/kolla/")
+ return os.environ.get("KOLLA_ETC", "/etc/kolla/")
[docs]def get_kollacli_home():
- return os.environ.get("KOLLA_CLI_HOME", "/usr/share/kolla/kollacli/")
+ return os.environ.get("KOLLA_CLI_HOME", "/usr/share/kolla/kollacli/")
[docs]def get_kollacli_etc():
- return os.environ.get("KOLLA_CLI_ETC", "/etc/kolla/kollacli/")
+ return os.environ.get("KOLLA_CLI_ETC", "/etc/kolla/kollacli/")
[docs]def get_group_vars_dir():
- return os.path.join(get_kolla_home(), 'ansible/group_vars')
+ return os.path.join(get_kolla_home(), 'ansible/group_vars')
[docs]def get_host_vars_dir():
- return os.path.join(get_kolla_home(), 'ansible/host_vars')
+ return os.path.join(get_kolla_home(), 'ansible/host_vars')
[docs]def get_ansible_lock_path():
- return os.path.join(get_kollacli_home(), 'ansible.lock')
+ return os.path.join(get_kollacli_home(), 'ansible.lock')
[docs]def get_kolla_actions_path():
- return os.path.join(get_kollacli_home(), 'tools', 'kolla_actions.py')
+ return os.path.join(get_kollacli_home(), 'tools', 'kolla_actions.py')
[docs]def get_kolla_log_file_size():
- envvar = 'KOLLA_LOG_FILE_SIZE'
- size_str = os.environ.get(envvar, '500000')
+ envvar = 'KOLLA_LOG_FILE_SIZE'
+ size_str = os.environ.get(envvar, '500000')
try:
size = int(size_str)
except Exception:
raise InvalidArgument(
- u._('Environmental variable ({env_var}) is not an '
- 'integer ({log_size}).')
+ u._('Environmental variable ({env_var}) is not an '
+ 'integer ({log_size}).')
.format(env_var=envvar, log_size=size_str))
return size
[docs]def get_property_list_length():
- envvar = 'KOLLA_PROP_LIST_LENGTH'
- length_str = os.environ.get(envvar, '50')
+ envvar = 'KOLLA_PROP_LIST_LENGTH'
+ length_str = os.environ.get(envvar, '50')
try:
length = int(length_str)
except Exception:
raise InvalidArgument(
- u._('Environmental variable ({env_var}) is not an '
- 'integer ({prop_length}).')
+ u._('Environmental variable ({env_var}) is not an '
+ 'integer ({prop_length}).')
.format(env_var=envvar, prop_length=length_str))
return length
[docs]def get_admin_user():
- return os.environ.get("KOLLA_CLI_ADMIN_USER", "kolla")
+ return os.environ.get("KOLLA_CLI_ADMIN_USER", "kolla")
[docs]def get_setup_user():
- return os.environ.get("KOLLA_CLI_SETUP_USER", "root")
+ return os.environ.get("KOLLA_CLI_SETUP_USER", "root")
[docs]def get_ansible_command(playbook=False):
@@ -183,26 +184,26 @@
python is py3, prefix the ansible command with a py2
interpreter.
"""
- cmd = 'ansible'
+ cmd = 'ansible'
if playbook:
- cmd = 'ansible-playbook'
+ cmd = 'ansible-playbook'
if sys.version_info[0] >= 3:
- # running with py3, find a py2 interpreter for ansible
+ # running with py3, find a py2 interpreter for ansible
py2_path = None
- usr_bin = os.path.join('/', 'usr', 'bin')
+ usr_bin = os.path.join('/', 'usr', 'bin')
for fname in os.listdir(usr_bin):
- if (fname.startswith('python2.') and
+ if (fname.startswith('python2.') and
os.path.isfile(os.path.join(usr_bin, fname))):
- suffix = fname.split('.')[1]
+ suffix = fname.split('.')[1]
if suffix.isdigit():
py2_path = os.path.join(usr_bin, fname)
break
if py2_path is None:
raise Exception(
- u._('ansible-playbook requires python2 and no '
- 'python2 interpreter found in {path}.')
+ u._('ansible-playbook requires python2 and no '
+ 'python2 interpreter found in {path}.')
.format(path=usr_bin))
- cmd = '%s %s' % (py2_path, os.path.join(usr_bin, cmd))
+ cmd = '%s %s' % (py2_path, os.path.join(usr_bin, cmd))
return cmd
@@ -221,14 +222,15 @@
"""run a system command
return:
- - err_msg: empty string=command succeeded
- not None=command failed
- - output: string: all the output of the run command
+ - err_msg: empty string=command succeeded
+ not None=command failed
+ - output: string: all the output of the run command
+
"""
err = None
output = None
try:
- process = subprocess.Popen(cmd, shell=True, # nosec
+ process = subprocess.Popen(cmd, shell=True, # nosec
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, err = process.communicate()
@@ -238,12 +240,48 @@
err = safe_decode(err)
output = safe_decode(output)
if process.returncode != 0:
- err = (u._('Command failed. : {error}')
+ err = (u._('Command failed. : {error}')
.format(error=err))
if print_output:
LOG.info(output)
return err, output
+
+[docs]def change_password(file_path, pname, pvalue=None, public_key=None,
+ private_key=None, clear=False):
+ """change password in passwords.yml file
+
+ file_path: path to passwords file
+ pname: name of password
+ pvalue: value of password when not ssh key
+ public_key: public ssh key
+ private_key: private ssh key
+ clear: flag to remove password
+
+ If clear, and password exists, remove it from the password file.
+ If clear, and password doesn't exists, nothing is done.
+ If not clear, and key is not found, the new password will be added.
+ If not clear, and key is found, edit password in place.
+
+ The passwords file contains both key-value pairs and key-dictionary
+ pairs.
+ """
+ read_data = sync_read_file(file_path)
+ file_pwds = yaml.safe_load(read_data)
+ if clear:
+ # clear
+ if pname in file_pwds:
+ del file_pwds[pname]
+ else:
+ # edit
+ if pvalue:
+ file_pwds[pname] = pvalue
+ elif private_key:
+ file_pwds[pname] = {'private_key': private_key,
+ 'public_key': public_key}
+ write_data = yaml.safe_dump(file_pwds, default_flow_style=False)
+ sync_write_file(file_path, write_data)
+
[docs]def change_property(file_path, property_dict, clear=False):
"""change property with a file
@@ -258,20 +296,20 @@
If not clear, and key is found, edit property in place.
"""
cloned_dict = copy.copy(property_dict)
- group_info = grp.getgrnam('kolla')
+ group_info = grp.getgrnam('kolla')
if not os.path.exists(file_path):
- with open(file_path, 'a'):
+ with open(file_path, 'a'):
os.utime(file_path, None)
os.chown(file_path, -1, group_info.gr_gid)
new_contents = []
read_data = sync_read_file(file_path)
- lines = read_data.split('\n')
+ lines = read_data.split('\n')
last_line_empty = False
for line in lines:
line = line.rstrip()
- # yank spurious empty lines
+ # yank spurious empty lines
if line:
last_line_empty = False
else:
@@ -279,43 +317,43 @@
continue
last_line_empty = True
- split_line = line.split(':', 1)
+ split_line = line.split(':', 1)
if len(split_line) > 1:
split_key = split_line[0]
split_key.rstrip()
if split_key in cloned_dict:
if clear:
- # clear existing property
+ # clear existing property
continue
- # edit existing property
- line = '%s: "%s"' % (split_key, cloned_dict[split_key])
- # clear out the key after we are done, all existing keys
- # will be appended at the end (or for clear, ignored)
+ # edit existing property
+ line = '%s: "%s"' % (split_key, cloned_dict[split_key])
+ # clear out the key after we are done, all existing keys
+ # will be appended at the end (or for clear, ignored)
del cloned_dict[split_key]
new_contents.append(line)
if not clear:
- # add new properties to file
+ # add new properties to file
for key, value in cloned_dict.items():
- line = '%s: "%s"' % (key, value)
+ line = '%s: "%s"' % (key, value)
new_contents.append(line)
- write_data = '\n'.join(new_contents)
+ write_data = '\n'.join(new_contents)
sync_write_file(file_path, write_data)
-[docs]def sync_read_file(path, mode='r'):
+[docs]def sync_read_file(path, mode='r'):
"""synchronously read file
return file data
"""
lock = None
try:
- lock = Lock(path, 'sync_read')
+ lock = Lock(path, 'sync_read')
locked = lock.wait_acquire()
if not locked:
raise Exception(
- u._('unable to read file {path} '
- 'as it was locked.')
+ u._('unable to read file {path} '
+ 'as it was locked.')
.format(path=path))
with open(path, mode) as data_file:
data = data_file.read()
@@ -325,25 +363,25 @@
return safe_decode(data)
-[docs]def sync_write_file(path, data, mode='w'):
+[docs]def sync_write_file(path, data, mode='w'):
"""synchronously write file"""
ansible_lock = None
lock = None
try:
- ansible_lock = Lock(get_ansible_lock_path(), 'sync_write')
+ ansible_lock = Lock(get_ansible_lock_path(), 'sync_write')
locked = ansible_lock.wait_acquire()
if not locked:
raise Exception(
- u._('unable to get ansible lock while writing to {path} '
- 'as it was locked.')
+ u._('unable to get ansible lock while writing to {path} '
+ 'as it was locked.')
.format(path=path))
- lock = Lock(path, 'sync_write')
+ lock = Lock(path, 'sync_write')
locked = lock.wait_acquire()
if not locked:
raise Exception(
- u._('unable to write file {path} '
- 'as it was locked.')
+ u._('unable to write file {path} '
+ 'as it was locked.')
.format(path=path))
with open(path, mode) as data_file:
data_file.write(data)
@@ -375,48 +413,84 @@
key = safe_decode(key)
value = safe_decode(value)
new_obj[key] = value
-
else:
- try:
- new_obj = obj_to_decode.decode('utf-8')
- except AttributeError: # nosec
- # py3 will raise if text is already a string
- new_obj = obj_to_decode
+ new_obj = obj_to_decode
+ if not isinstance(obj_to_decode, six.text_type):
+ # object is not unicode
+ new_obj = obj_to_decode.decode('utf-8')
return new_obj
[docs]def is_string_true(string):
"""Return boolean True if string represents a true value (None is False)"""
- true_values = ['yes', 'true']
+ true_values = ['yes', 'true']
if string is not None and string.lower() in true_values:
return True
else:
return False
-[docs]def check_arg(param, param_name, expected_type, none_ok=False, empty_ok=False):
+[docs]def convert_lists_to_string(tuples, parsed_args):
+ """convert lists to strings
+
+ Because of the way cliff processes strings for tables, if a list
+ has non-ascii chars in it, they would display as unicode bytes
+ (\u0414\u0435\u043a\u0430\u0442). By converting
+ the list to string here, the proper non-ascii chars are displayed.
+
+ This will only change the lists when the output is to a table. It cannot
+ be changed if the display output is json, yaml, etc.
+ """
+ if parsed_args.formatter and parsed_args.formatter != 'table':
+ # not table output, leave it as-is
+ return tuples
+
+ new_tuples = []
+ for data_tuple in tuples:
+ new_items = []
+ items = list(data_tuple)
+ for item in items:
+ if isinstance(item, list):
+ item = convert_list_to_string(item)
+ new_items.append(item)
+ data_tuple = tuple(new_items)
+ new_tuples.append(data_tuple)
+ return new_tuples
+
+
+
+[docs]def check_arg(param, param_name, expected_type, none_ok=False, empty_ok=False,
+ display_param=True):
if param is None:
if none_ok:
return
- # None arg
+ # None arg
raise MissingArgument(param_name)
if ((isinstance(param, six.string_types) or
isinstance(param, dict) or
isinstance(param, list)) and
not param and not empty_ok):
- # empty string, dict or list
+ # empty string, dict or list
raise MissingArgument(param_name)
- # normalize expected string types for py2 and py3
+ # normalize expected string types for py2 and py3
if expected_type is str:
expected_type = six.string_types
if not isinstance(param, expected_type):
- # wrong type
- raise InvalidArgument(u._('{name} ({param}) is not a {type}')
- .format(name=param_name, param=param,
- type=expected_type))
+ # wrong type
+ if display_param:
+ raise InvalidArgument(u._('{name} ({param}) is not a {type}')
+ .format(name=param_name, param=param,
+ type=expected_type))
+ else:
+ raise InvalidArgument(u._('{name} is not a {type}')
+ .format(name=param_name,
+ type=expected_type))
[docs]class Lock(object):
@@ -428,13 +502,13 @@
works then it seems better / less complicated for our needs.
"""
- def __init__(self, lockpath, owner='unknown owner', use_flock=True):
+ def __init__(self, lockpath, owner='unknown owner', use_flock=True):
self.lockpath = lockpath
self.pid = str(os.getpid())
self.fd = None
self.owner = owner
self.current_pid = -1
- self.current_owner = ''
+ self.current_owner = ''
self.use_flock = use_flock
[docs] def acquire(self):
@@ -445,19 +519,19 @@
return self._acquire_pidfile()
except Exception as e:
if not os.path.exists(self.lockpath):
- raise Exception('Lock file (%s) is missing'
+ raise Exception('Lock file (%s) is missing'
% self.lockpath)
- # it is ok to fail to acquire, we just return that we failed
- LOG.debug('Exception in acquire lock. '
- 'path: %s pid: %s owner: %s error: %s' %
+ # it is ok to fail to acquire, we just return that we failed
+ LOG.debug('Exception in acquire lock. '
+ 'path: %s pid: %s owner: %s error: %s' %
(self.lockpath, self.pid, self.owner, str(e)))
def _acquire_pidfile(self):
if not self.is_owned_by_me():
fd = os.open(self.lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR)
- with os.fdopen(fd, 'a') as f:
- f.write(self.pid + '\n' + self.owner)
+ with os.fdopen(fd, 'a') as f:
+ f.write(self.pid + '\n' + self.owner)
return self.is_owned_by_me()
def _acquire_flock(self):
@@ -479,15 +553,15 @@
"""Returns True if we own the lock or False otherwise"""
try:
if self.use_flock:
- raise Exception(u._('Invalid use of is_owned_by_me while'
- 'using flock'))
+ raise Exception(u._('Invalid use of is_owned_by_me while'
+ 'using flock'))
if not os.path.exists(self.lockpath):
- # lock doesn't exist, just return
+ # lock doesn't exist, just return
return False
fd = os.open(self.lockpath, os.O_RDONLY)
- with os.fdopen(fd, 'r') as f:
- contents = f.read(2048).strip().split('\n')
+ with os.fdopen(fd, 'r') as f:
+ contents = f.read(2048).strip().split('\n')
if len(contents) > 0:
self.current_pid = contents[0]
if len(contents) > 1:
@@ -498,9 +572,9 @@
else:
return False
except Exception as e:
- # it is ok to fail to acquire, we just return that we failed
- LOG.debug('Exception in is_owned_by_me lock check. '
- 'path: %s pid: %s owner: %s error: %s' %
+ # it is ok to fail to acquire, we just return that we failed
+ LOG.debug('Exception in is_owned_by_me lock check. '
+ 'path: %s pid: %s owner: %s error: %s' %
(self.lockpath, self.pid, self.owner, str(e)))
return False
@@ -511,11 +585,11 @@
else:
self._release_pidfile()
except Exception:
- # this really shouldn't happen unless for some reason
- # two areas in the same process try to release the lock
- # at the same time and if that happens you want to see
- # an error about it
- LOG.error('Error releasing lock', exc_info=True)
+ # this really shouldn't happen unless for some reason
+ # two areas in the same process try to release the lock
+ # at the same time and if that happens you want to see
+ # an error about it
+ LOG.error('Error releasing lock', exc_info=True)
return False
def _release_pidfile(self):
@@ -527,7 +601,7 @@
try:
fcntl.flock(self.fd, fcntl.LOCK_UN)
except Exception as e:
- LOG.debug('Exception while releasing lock: %s' % str(e))
+ LOG.debug('Exception while releasing lock: %s' % str(e))
finally:
os.close(self.fd)
return True
@@ -537,24 +611,24 @@
@staticmethod
[docs] def get_child_pids(pid, child_pids=[]):
"""get child pids of parent pid"""
- # This ps command will return child pids of parent pid, separated by
- # newlines.
- err_msg, output = run_cmd('ps --ppid %s -o pid=""' % pid,
+ # This ps command will return child pids of parent pid, separated by
+ # newlines.
+ err_msg, output = run_cmd('ps --ppid %s -o pid=""' % pid,
print_output=False)
- # err_msg is expected when pid has no children
+ # err_msg is expected when pid has no children
if not err_msg:
output = output.strip()
- if '\n' in output:
- ps_pids = output.split('\n')
+ if '\n' in output:
+ ps_pids = output.split('\n')
else:
ps_pids = [output]
if ps_pids:
child_pids.extend(ps_pids)
- # recurse through children to get all child pids
+ # recurse through children to get all child pids
for ps_pid in ps_pids:
PidManager.get_child_pids(ps_pid, child_pids)
return child_pids
@@ -591,7 +665,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_modules/kollacli/shell.html b/doc/build/html/_modules/kollacli/shell.html
index ff9e74f..5593a81 100644
--- a/doc/build/html/_modules/kollacli/shell.html
+++ b/doc/build/html/_modules/kollacli/shell.html
@@ -6,7 +6,7 @@
- kollacli.shell — kollacli 3.0.1.dev435 documentation
+ kollacli.shell — kollacli 3.0.1.dev463 documentation
@@ -14,7 +14,7 @@
-
+
@@ -36,7 +36,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
@@ -47,19 +47,19 @@
Source code for kollacli.shell
-# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# 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.
+# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
+#
+# 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.
"""Command-line interface to Kolla"""
import logging
import os
@@ -77,32 +77,32 @@
LOG = logging.getLogger(__name__)
-VERSION = '0.3'
+VERSION = '0.3'
[docs]class KollaCli(App):
def __init__(self):
super(KollaCli, self).__init__(
- description=u._('Command-Line Client for OpenStack Kolla'),
+ description=u._('Command-Line Client for OpenStack Kolla'),
version=VERSION,
- command_manager=CommandManager('kolla.cli'),
+ command_manager=CommandManager('kolla.cli'),
)
inventory_path = os.path.join(get_kollacli_etc(),
INVENTORY_PATH)
if os.path.isfile(inventory_path) is False:
err_string = u._(
- 'Required file ({inventory}) does not exist.\n'
- 'Please re-install the kollacli to '
- 'recreate the file.').format(inventory=inventory_path)
+ 'Required file ({inventory}) does not exist.\n'
+ 'Please re-install the kollacli to '
+ 'recreate the file.').format(inventory=inventory_path)
raise CommandError(err_string)
- # set up logging and test that user running shell is part
- # of kolla group
+ # set up logging and test that user running shell is part
+ # of kolla group
ClientApi()
- # paramiko log is very chatty, tune it down
- logging.getLogger('paramiko').setLevel(logging.WARNING)
+ # paramiko log is very chatty, tune it down
+ logging.getLogger('paramiko').setLevel(logging.WARNING)
self.dump_stack_trace = False
@@ -111,7 +111,7 @@
shell = KollaCli()
return shell.run(argv)
-if __name__ == "__main__":
+if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
@@ -146,7 +146,7 @@
modules |
- kollacli 3.0.1.dev435 documentation »
+ kollacli 3.0.1.dev463 documentation »
Module code »
diff --git a/doc/build/html/_static/pygments.css b/doc/build/html/_static/pygments.css
index 57eadc0..8213e90 100644
--- a/doc/build/html/_static/pygments.css
+++ b/doc/build/html/_static/pygments.css
@@ -4,8 +4,10 @@
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
+.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
diff --git a/doc/build/html/genindex.html b/doc/build/html/genindex.html
index e08ddfb..1a067f3 100644
--- a/doc/build/html/genindex.html
+++ b/doc/build/html/genindex.html
@@ -7,7 +7,7 @@
- Index — kollacli 3.0.1.dev435 documentation
+ Index — kollacli 3.0.1.dev463 documentation
@@ -15,7 +15,7 @@
-
+
@@ -105,7 +105,7 @@
- add_host() (kollacli.api.group.GroupApi.Group method)
+ add_host() (kollacli.api.group.Group method)
@@ -119,7 +119,7 @@
- add_service() (kollacli.api.group.GroupApi.Group method)
+ add_service() (kollacli.api.group.Group method)
@@ -195,6 +195,10 @@