Skip to content
Browse files

Support v1.0 and v1.1 API versions.

  • Loading branch information...
1 parent 269099c commit 71669def2aa4dc9658b9a4c37742a20f6125180a @cluther cluther committed Nov 11, 2011
View
2 GNUmakefile
@@ -37,4 +37,6 @@ clean:
rm -rf build dist *.egg-info
find . -name '*.pyc' | xargs rm
cd $(NOVACLIENT_DIR) ; rm -rf build dist *.egg-info
+ rm -f $(BIN_DIR)/nova
+ cd $(LIB_DIR) ; rm -Rf *.egg site.py easy-install.pth
View
27 README.markdown
@@ -1,16 +1,16 @@
# ZenPacks.zenoss.OpenStack
-Please watch the [Monitoring OpenStack][] video for a quick introduction that
+Please watch the [Monitoring OpenStack][]* video for a quick introduction that
covers most of the details below.
+**\*** The video is of an early version of the ZenPack that doesn't have as
+many options when adding an OpenStack endpoint. See the usage notes below for
+help with the new fields available on the *Add OpenStack* dialog.
+
## About
This project is a [Zenoss][] extension (ZenPack) that allows for monitoring of
OpenStack. This means that you can monitor the flavors, images and servers
-from a user or consumer perspective. OpenStack Compute v1.1 (Cactus) is known
-to be supported. Specifically this means that Rackspace's CloudServers can be
-monitored.
-
-In the future it is likely that support for monitoring OpenStack Storage
-(Swift) will be added.
+from a user or consumer perspective. OpenStack API versions 1.0 and 1.1 are
+supported.
[OpenStack][] is a global collaboration of developers and cloud computing
technologists producing the ubiquitous open source cloud computing platform
@@ -28,7 +28,7 @@ versions are supported. You can download the free Core version of Zenoss from
Download the [latest OpenStack ZenPack][]. Copy this file to your Zenoss
server and run the following commands as the zenoss user.
- zenpack --install ZenPacks.zenoss.OpenStack-1.0.2-py2.6.egg
+ zenpack --install ZenPacks.zenoss.OpenStack-1.1.0-py2.6.egg
zenoss restart
### Developer Installation (link mode)
@@ -48,10 +48,11 @@ You'll find a new option labeled, "Add OpenStack."
Choose that option and you'll be presented with a dialog asking for the
following inputs.
- 1. Hostname or IP - An example would be rackspacecloud.com.
- 2. Auth URL - For Rackspace this would be https://auth.api.rackspacecloud.com/v1.0
- 3. Username - Same username used to login to OpenStack web interface
- 4. API Key - Can be found by going to "Your Account/API Access"
+ 1. Username - Same username used to login to OpenStack web interface
+ 2. API Key - Can be found by going to "Your Account/API Access"
+ 3. Project ID - This can be left blank if you don't know what it is
+ 4. Auth URL - For Rackspace this would be https://auth.api.rackspacecloud.com/v1.0
+ 5. Region Name - This can be left blank if you don't know what it is
Once you click Add, Zenoss will contact the OpenStack API and discover
servers, images and flavors. Once it is complete you'll find a new device in
@@ -99,6 +100,6 @@ when the graphs option is chosen for the OpenStack server.
[Monitoring OpenStack]: <http://www.youtube.com/watch?v=-43gnQLbX9g>
[Zenoss]: <http://www.zenoss.com/>
-[latest OpenStack ZenPack]: <https://github.com/downloads/zenoss/ZenPacks.zenoss.OpenStack/ZenPacks.zenoss.OpenStack-1.0.2-py2.6.egg>
+[latest OpenStack ZenPack]: <https://github.com/downloads/zenoss/ZenPacks.zenoss.OpenStack/ZenPacks.zenoss.OpenStack-1.1.0-py2.6.egg>
[git repository]: <https://github.com/zenoss/ZenPacks.zenoss.OpenStack>
[OpenStack]: <http://www.openstack.org/>
View
37 ZenPacks/zenoss/OpenStack/Server.py
@@ -16,6 +16,7 @@
from Products.ZenModel.ZenossSecurity import ZEN_CHANGE_DEVICE
from Products.ZenRelations.RelSchema import ToMany, ToManyCont, ToOne
+
class Server(DeviceComponent, ManagedEntity):
meta_type = portal_type = "OpenStackServer"
@@ -24,8 +25,8 @@ class Server(DeviceComponent, ManagedEntity):
serverBackupEnabled = None # False
serverBackupDaily = None # DISABLED
serverBackupWeekly = None # DISABLED
- publicIp = None # 50.57.74.222
- privateIp = None # 10.182.13.13
+ publicIps = [] # ['50.57.74.222']
+ privateIps = [] # ['10.182.13.13']
hostId = None # a84303c0021aa53c7e749cbbbfac265f
_properties = ManagedEntity._properties + (
@@ -34,8 +35,8 @@ class Server(DeviceComponent, ManagedEntity):
{'id': 'serverBackupEnabled', 'type': 'boolean', 'mode': ''},
{'id': 'serverBackupDaily', 'type': 'string', 'mode': ''},
{'id': 'serverBackupWeekly', 'type': 'string', 'mode': ''},
- {'id': 'publicIp', 'type': 'string', 'mode': ''},
- {'id': 'privateIp', 'type': 'string', 'mode': ''},
+ {'id': 'publicIps', 'type': 'lines', 'mode': ''},
+ {'id': 'privateIps', 'type': 'lines', 'mode': ''},
{'id': 'hostId', 'type': 'string', 'mode': ''},
)
@@ -58,12 +59,12 @@ class Server(DeviceComponent, ManagedEntity):
)
factory_type_information = ({
- 'actions': ({
- 'id': 'perfConf',
- 'name': 'Template',
- 'action': 'objTemplates',
- 'permissions': (ZEN_CHANGE_DEVICE,),
- },),
+ 'actions': ({
+ 'id': 'perfConf',
+ 'name': 'Template',
+ 'action': 'objTemplates',
+ 'permissions': (ZEN_CHANGE_DEVICE,),
+ },),
},)
# Query for events by id instead of name.
@@ -98,14 +99,15 @@ def getIconPath(self):
return '/++resource++openstack/img/openstack.png'
def getGuestDevice(self):
- if self.publicIp:
- device = self.dmd.Devices.findDeviceByIdOrIp(self.publicIp)
- if device:
- return device
+ if len(self.publicIps) > 0:
+ for public_ip in self.publicIps:
+ device = self.dmd.Devices.findDeviceByIdOrIp(public_ip)
+ if device:
+ return device
- ip = self.dmd.Networks.findIp(self.publicIp)
- if ip:
- return ip.device()
+ ip = self.dmd.Networks.findIp(public_ip)
+ if ip:
+ return ip.device()
return None
@@ -124,4 +126,3 @@ def getDefaultGraphDefs(self, drange=None):
url=guest_graph['url']))
return graphs
-
View
10 ZenPacks/zenoss/OpenStack/__init__.py
@@ -23,9 +23,13 @@
from Products.ZenUtils.Utils import monkeypatch, zenPath
from Products.Zuul.interfaces import ICatalogTool
+
class ZenPack(ZenPackBase):
packZProperties = [
('zOpenStackAuthUrl', '', 'string'),
+ ('zOpenStackProjectId', '', 'string'),
+ ('zOpenStackInsecure', False, 'boolean'),
+ ('zOpenStackRegionName', '', 'string'),
]
def install(self, app):
@@ -54,17 +58,20 @@ def removePluginSymlink(self):
"\"(device = '%s' and component = '%s')\""
" % (me.device().getDmdKey(), me.id)")
+
@monkeypatch('Products.ZenModel.Device.Device')
def getOpenStackServer(self):
catalog = ICatalogTool(self.dmd)
for record in catalog.search('ZenPacks.zenoss.OpenStack.Server.Server'):
server = record.getObject()
- if server.publicIp == self.manageIp:
+ if server.publicIps:
return server
# This would be much cleaner with the new "original" method support in
# Avalon's monkeypatch decorator. For now we have to do it manually.
orig_getExpandedLinks = copy.copy(Device.getExpandedLinks.im_func)
+
+
def openstack_getExpandedLinks(self):
links = orig_getExpandedLinks(self)
server = self.getOpenStackServer()
@@ -76,4 +83,3 @@ def openstack_getExpandedLinks(self):
return links
Device.getExpandedLinks = openstack_getExpandedLinks
-
View
18 ZenPacks/zenoss/OpenStack/browser/resources/js/Endpoint.js
@@ -261,8 +261,8 @@ ZC.OpenStackServerPanel = Ext.extend(ZC.OpenStackComponentGridPanel, {
{name: 'serverStatus'},
{name: 'flavor'},
{name: 'image'},
- {name: 'publicIp'},
- {name: 'privateIp'},
+ {name: 'publicIps'},
+ {name: 'privateIps'},
{name: 'serverBackupEnabled'},
{name: 'monitor'},
{name: 'monitored'}
@@ -309,16 +309,14 @@ ZC.OpenStackServerPanel = Ext.extend(ZC.OpenStackComponentGridPanel, {
renderer: Zenoss.render.entityLinkFromGrid,
width: 140
},{
- id: 'publicIp',
- dataIndex: 'publicIp',
- header: _t('Public IP'),
- sortable: true,
+ id: 'publicIps',
+ dataIndex: 'publicIps',
+ header: _t('Public IPs'),
width: 85
},{
- id: 'privateIp',
- dataIndex: 'privateIp',
- header: _t('Private IP'),
- sortable: true,
+ id: 'privateIps',
+ dataIndex: 'privateIps',
+ header: _t('Private IPs'),
width: 85
},{
id: 'serverBackupEnabled',
View
47 ZenPacks/zenoss/OpenStack/browser/resources/js/OpenStack.js
@@ -17,33 +17,40 @@ var addOpenStack = new Zenoss.Action({
border: false,
items: [{
xtype: 'textfield',
- name: 'hostname',
- fieldLabel: _t('Hostname or IP'),
- id: "openstackTitleField",
+ name: 'username',
+ fieldLabel: _t('Username'),
+ id: "openstack_username",
width: 260,
allowBlank: false
}, {
xtype: 'textfield',
- name: 'authUrl',
- fieldLabel: _t('Auth URL'),
- id: "openstackAuthUrlField",
+ name: 'api_key',
+ fieldLabel: _t('API Key'),
+ id: "openstack_api_key",
width: 260,
allowBlank: false
}, {
xtype: 'textfield',
- name: 'username',
- fieldLabel: _t('Username'),
- id: "openstackUsernameField",
+ name: 'project_id',
+ fieldLabel: _t('Project ID'),
+ id: "openstack_project_id",
width: 260,
- allowBlank: false
+ allowBlank: true
}, {
xtype: 'textfield',
- name: 'apiKey',
- inputType: 'password',
- fieldLabel: _t('API Key'),
- id: "openstackApiKeyField",
+ name: 'auth_url',
+ fieldLabel: _t('Auth URL'),
+ id: "openstack_auth_url",
width: 260,
- allowBlank: false
+ allowBlank: true,
+ value: 'https://auth.api.rackspacecloud.com/v1.0'
+ }, {
+ xtype: 'textfield',
+ name: 'region_name',
+ fieldLabel: _t('Region Name'),
+ id: "openstack_region_name",
+ width: 260,
+ allowBlank: true
}],
buttons: [{
xtype: 'DialogButton',
@@ -105,8 +112,10 @@ var NS = Ext.namespace('Zenoss.zenpacks.OpenStack');
NS.OpenStackEndpointInspector = Ext.extend(Zenoss.inspector.DeviceInspector, {
constructor: function(config) {
NS.OpenStackEndpointInspector.superclass.constructor.call(this, config);
- this.addPropertyTpl(_t('Authentication URL'), '{values.authUrl}');
this.addPropertyTpl(_t('Username'), '{values.username}');
+ this.addPropertyTpl(_t('Project ID'), '{values.project_id}');
+ this.addPropertyTpl(_t('Auth URL'), '{values.auth_url}');
+ this.addPropertyTpl(_t('Region Name'), '{values.region_name}');
this.addPropertyTpl(_t('Total Servers'), '{values.serverCount}');
this.addPropertyTpl(_t('Total Flavors'), '{values.flavorCount}');
this.addPropertyTpl(_t('Total Images'), '{values.imageCount}');
@@ -124,8 +133,8 @@ NS.OpenStackServerInspector = Ext.extend(Zenoss.inspector.ComponentInspector, {
'{[Zenoss.render.link(values.guestDevice)]}');
this.addPropertyTpl(_t('Server Status'), '{values.serverStatus}');
- this.addPropertyTpl(_t('Public IP'), '{values.publicIp}');
- this.addPropertyTpl(_t('Private IP'), '{values.privateIp}');
+ this.addPropertyTpl(_t('Public IPs'), '{values.publicIps}');
+ this.addPropertyTpl(_t('Private IPs'), '{values.privateIps}');
this.addPropertyTpl(_t('Flavor'),
'{[Zenoss.render.link(values.flavor)]}');
@@ -139,6 +148,4 @@ NS.OpenStackServerInspector = Ext.extend(Zenoss.inspector.ComponentInspector, {
Ext.reg('OpenStackServerInspector', NS.OpenStackServerInspector);
Zenoss.inspector.registerInspector(
'OpenStackServer', 'OpenStackServerInspector');
-
}());
-
View
8 ZenPacks/zenoss/OpenStack/deviceloaders.py
@@ -19,13 +19,15 @@
from Products.Zuul import getFacade
from Products.ZenModel.interfaces import IDeviceLoader
+
class OpenStackLoader(object):
"""
Loader for the OpenStack ZenPack.
"""
implements(IDeviceLoader)
- def load_device(self, dmd, hostname, authUrl, username, apiKey):
- return getFacade('openstack', dmd).addOpenStack(
- hostname, authUrl, username, apiKey)
+ def load_device(self, dmd, username, api_key, project_id, auth_url,
+ region_name=None):
+ return getFacade('openstack', dmd).addOpenStack(
+ username, api_key, project_id, auth_url, region_name=region_name)
View
21 ZenPacks/zenoss/OpenStack/facades.py
@@ -14,33 +14,39 @@
import logging
log = logging.getLogger('zen.OpenStackFacade')
+from urlparse import urlparse
+
from zope.interface import implements
from Products.Zuul.facades import ZuulFacade
from Products.Zuul.utils import ZuulMessageFactory as _t
-from .interfaces import IOpenStackFacade
+from ZenPacks.zenoss.OpenStack.interfaces import IOpenStackFacade
OPENSTACK_DEVICE_PATH = "/Devices/OpenStack"
class OpenStackFacade(ZuulFacade):
implements(IOpenStackFacade)
- def addOpenStack(self, hostname, authUrl, username, apiKey):
- """
- Handles adding a new OpenStack endpoint to the system.
- """
+ def addOpenStack(self, username, api_key, project_id, auth_url,
+ region_name=None):
+ """Add a new OpenStack endpoint to the system."""
+ parsed_url = urlparse(auth_url)
+ hostname = parsed_url.hostname
+
# Verify that this device does not already exist.
deviceRoot = self._dmd.getDmdRoot("Devices")
device = deviceRoot.findDeviceByIdExact(hostname)
if device:
return False, _t("A device named %s already exists." % hostname)
zProperties = {
- 'zOpenStackAuthUrl': authUrl,
'zCommandUsername': username,
- 'zCommandPassword': apiKey,
+ 'zCommandPassword': api_key,
+ 'zOpenStackProjectId': project_id,
+ 'zOpenStackAuthUrl': auth_url,
+ 'zOpenStackRegionName': region_name or '',
}
perfConf = self._dmd.Monitors.getPerformanceMonitor('localhost')
@@ -51,4 +57,3 @@ def addOpenStack(self, hostname, authUrl, username, apiKey):
zProperties=zProperties)
return True, jobStatus.id
-
View
23 ZenPacks/zenoss/OpenStack/info.py
@@ -27,6 +27,7 @@
from .interfaces import IEndpointInfo, IFlavorInfo, IImageInfo, IServerInfo
+
class OpenStackComponentInfo(ComponentInfo):
@property
def entity(self):
@@ -45,12 +46,20 @@ class EndpointInfo(DeviceInfo):
adapts(Endpoint)
@property
- def authUrl(self):
+ def username(self):
+ return self._object.primaryAq().zCommandUsername
+
+ @property
+ def project_id(self):
+ return self._object.primaryAq().zOpenStackProjectId
+
+ @property
+ def auth_url(self):
return self._object.primaryAq().zOpenStackAuthUrl
@property
- def username(self):
- return self._object.primaryAq().zCommandUsername
+ def region_name(self):
+ return self._object.primaryAq().zOpenStackRegionName
@property
def flavorCount(self):
@@ -64,6 +73,7 @@ def imageCount(self):
def serverCount(self):
return self._object.servers.countObjects()
+
class FlavorInfo(OpenStackComponentInfo):
implements(IFlavorInfo)
adapts(Flavor)
@@ -83,6 +93,7 @@ def flavorDiskString(self):
def serverCount(self):
return self._object.servers.countObjects()
+
class ImageInfo(OpenStackComponentInfo):
implements(IImageInfo)
adapts(Image)
@@ -95,13 +106,14 @@ class ImageInfo(OpenStackComponentInfo):
def serverCount(self):
return self._object.servers.countObjects()
+
class ServerInfo(OpenStackComponentInfo):
implements(IServerInfo)
adapts(Server)
serverStatus = ProxyProperty('serverStatus')
- publicIp = ProxyProperty('publicIp')
- privateIp = ProxyProperty('privateIp')
+ publicIps = ProxyProperty('publicIps')
+ privateIps = ProxyProperty('privateIps')
serverBackupEnabled = ProxyProperty('serverBackupEnabled')
serverBackupDaily = ProxyProperty('serverBackupDaily')
serverBackupWeekly = ProxyProperty('serverBackupWeekly')
@@ -121,4 +133,3 @@ def image(self):
@info
def guestDevice(self):
return self._object.getGuestDevice()
-
View
18 ZenPacks/zenoss/OpenStack/interfaces.py
@@ -17,39 +17,43 @@
from Products.Zuul.interfaces.component import IComponentInfo
from Products.Zuul.utils import ZuulMessageFactory as _t
+
class IOpenStackFacade(IFacade):
def addEndpoint(self, target, email, password, collector):
- """
- Add OpenStack Endpoint.
- """
+ """Add OpenStack Endpoint."""
+
class IEndpointInfo(IDeviceInfo):
- authUrl = schema.Text(title=_t(u"Authentication URL"))
username = schema.Text(title=_t(u"Username"))
+ project_id = schema.Text(title=_t(u"Project ID"))
+ auth_url = schema.Text(title=_t(u"Auth URL"))
+ region_name = schema.Text(title=_t(u"Region Name"))
serverCount = schema.Int(title=_t(u"Total Servers"))
flavorCount = schema.Int(title=_t(u"Total Flavors"))
imageCount = schema.Int(title=_t(u"Total Images"))
+
class IFlavorInfo(IComponentInfo):
flavorRAMString = schema.Text(title=_t(u"Flavor RAM"))
flavorDiskString = schema.Text(title=_t(u"Flavor Disk"))
serverCount = schema.Int(title=_t(u"Server Count"))
+
class IImageInfo(IComponentInfo):
imageStatus = schema.Text(title=_t(u"Image Status"))
imageCreated = schema.Text(title=_t(u"Image Created"))
imageUpdated = schema.Text(title=_t(u"Image Updated"))
serverCount = schema.Int(title=_t(u"Server Count"))
+
class IServerInfo(IComponentInfo):
serverStatus = schema.Text(title=_t(u"Server Status"))
- publicIp = schema.Text(title=_t(u"Public IP"))
- privateIp = schema.Text(title=_t(u"Private IP"))
+ publicIps = schema.List(title=_t(u"Public IPs"))
+ privateIps = schema.List(title=_t(u"Private IPs"))
flavor = schema.Entity(title=_t(u"Server Flavor"))
image = schema.Entity(title=_t(u"Server Image"))
serverBackupEnabled = schema.Bool(title=_t(u"Server Backup Enabled"))
serverBackupDaily = schema.Text(title=_t(u"Server Backup Daily"))
serverBackupWeekly = schema.Text(title=_t(u"Server Backup Weekly"))
hostId = schema.Text(title=_t(u"Host ID"))
guestDevice = schema.Entity(title=_t(u"Guest Device"))
-
View
61 ZenPacks/zenoss/OpenStack/modeler/plugins/zenoss/OpenStack.py
@@ -14,36 +14,50 @@
import logging
log = logging.getLogger('zen.OpenStack')
+import types
+
from Products.DataCollector.plugins.CollectorPlugin import PythonPlugin
from Products.DataCollector.plugins.DataMaps import ObjectMap, RelationshipMap
from ZenPacks.zenoss.OpenStack.util import addLocalLibPath
addLocalLibPath()
import novaclient
+from novaclient.v1_0.client import Client as v1_0_Client
+from novaclient.v1_1.client import Client as v1_1_Client
class OpenStack(PythonPlugin):
deviceProperties = PythonPlugin.deviceProperties + (
- 'zOpenStackAuthUrl',
'zCommandUsername',
'zCommandPassword',
+ 'zOpenStackProjectId',
+ 'zOpenStackAuthUrl',
+ 'zOpenStackRegionName',
)
def collect(self, device, unused):
- client = novaclient.OpenStack(
+ client_class = None
+ if 'v1.1' in device.zOpenStackAuthUrl:
+ client_class = v1_1_Client
+ else:
+ client_class = v1_0_Client
+
+ region_name = None
+ if device.zOpenStackRegionName:
+ region_name = device.zOpenStackRegionName
+
+ client = client_class(
device.zCommandUsername,
device.zCommandPassword,
+ device.zOpenStackProjectId,
device.zOpenStackAuthUrl,
- )
+ region_name=region_name)
results = {}
- try:
- log.info('Requesting flavors')
- results['flavors'] = client.flavors.list()
- except Exception, ex:
- raise ex
+ log.info('Requesting flavors')
+ results['flavors'] = client.flavors.list()
log.info('Requesting images')
results['images'] = client.images.list()
@@ -71,12 +85,15 @@ def process(self, devices, results, unused):
images = []
for image in results['images']:
+ # Sometimes there's no created timestamp for an image.
+ created = getattr(image, 'created', '')
+
images.append(ObjectMap(data=dict(
id='image{0}'.format(image.id),
title=image.name, # Red Hat Enterprise Linux 5.5
imageId=image.id, # 55
imageStatus=image.status, # ACTIVE
- imageCreated=image.created, # 2010-09-17T07:19:20-05:00
+ imageCreated=created, # 2010-09-17T07:19:20-05:00
imageUpdated=image.updated, # 2010-09-17T07:19:20-05:00
)))
@@ -101,21 +118,27 @@ def process(self, devices, results, unused):
backup_schedule_daily = 'DISABLED'
backup_schedule_weekly = 'DISABLED'
- # IPs may not exist.
- public_ip = None
- private_ip = None
+ # IPs may not exist. They may also be either strings or lists.
+ public_ips = None
+ private_ips = None
try:
- public_ip = server.public_ip
+ public_ips = server.public_ip
except KeyError:
- public_ip = ''
+ public_ips = []
try:
- private_ip = server.private_ip
+ private_ips = server.private_ip
except KeyError:
- private_ip = ''
+ private_ips = []
+
+ if isinstance(public_ips, types.StringTypes):
+ public_ips = [public_ips]
+
+ if isinstance(private_ips, types.StringTypes):
+ private_ips = [private_ips]
- # Flavor and Image IDs could be specified in two ways.
+ # Flavor and Image IDs could be specified two different ways.
flavor_id = None
if hasattr(server, 'flavorId'):
flavor_id = int(server.flavorId)
@@ -136,8 +159,8 @@ def process(self, devices, results, unused):
serverBackupEnabled=backup_schedule_enabled, # False
serverBackupDaily=backup_schedule_daily, # DISABLED
serverBackupWeekly=backup_schedule_weekly, # DISABLED
- publicIp=public_ip, # 50.57.74.222
- privateIp=private_ip, # 10.182.13.13
+ publicIps=public_ips, # 50.57.74.222
+ privateIps=private_ips, # 10.182.13.13
setFlavorId=flavor_id, # 1
setImageId=image_id, # 55
View
7 ZenPacks/zenoss/OpenStack/objects/objects.xml
@@ -21,7 +21,10 @@ True
ZenPacks.zenoss.OpenStack.Endpoint
</property>
<property visible="True" type="float" id="zCommandCommandTimeout" >
-240.0
+300.0
+</property>
+<property visible="True" type="int" id="zCommandCycleTime" >
+300
</property>
<tomanycont id='rrdTemplates'>
<object id='OpenStackEndpoint' module='Products.ZenModel.RRDTemplate' class='RRDTemplate'>
@@ -43,7 +46,7 @@ True
4
</property>
<property type="string" id="commandTemplate" mode="w" >
-poll_openstack.py '${here/zOpenStackAuthUrl}' '${here/zCommandUsername}' '${here/zCommandPassword}'
+poll_openstack.py '${here/zCommandUsername}' '${here/zCommandPassword}' '${here/zOpenStackProjectId}' '${here/zOpenStackAuthUrl}' '${here/zOpenStackRegionName}'
</property>
<property type="int" id="cycletime" mode="w" >
300
View
51 ZenPacks/zenoss/OpenStack/poll_openstack.py
@@ -18,21 +18,31 @@
from util import addLocalLibPath
addLocalLibPath()
-import novaclient
+from novaclient.v1_0.client import Client as v1_0_Client
+from novaclient.v1_1.client import Client as v1_1_Client
-class OpenStackPoller(object):
- _authUrl = None
- _username = None
- _key = None
- def __init__(self, authUrl, username, key):
- self._authUrl = authUrl
+class OpenStackPoller(object):
+ def __init__(self, username, api_key, project_id, auth_url, region_name):
self._username = username
- self._key = key
+ self._api_key = api_key
+ self._project_id = project_id
+ self._auth_url = auth_url
+ self._region_name = region_name
def getData(self):
- client = novaclient.OpenStack(
- self._username, self._key, self._authUrl)
+ client_class = None
+ if 'v1.1' in self._auth_url:
+ client_class = v1_1_Client
+ else:
+ client_class = v1_0_Client
+
+ client = client_class(
+ self._username,
+ self._api_key,
+ self._project_id,
+ self._auth_url,
+ region_name=self._region_name or None)
data = {}
data['events'] = []
@@ -80,7 +90,7 @@ def getData(self):
summary='image status is {0}'.format(image.status),
component='image{0}'.format(image.id),
eventKey='imageStatus',
- eventClassKey = 'openstackImageStatus',
+ eventClassKey='openstackImageStatus',
imageStatus=image.status,
))
@@ -157,7 +167,7 @@ def getData(self):
summary='server status is {0}'.format(server.status),
component='server{0}'.format(server.id),
eventKey='serverStatus',
- eventClassKey = 'openstackServerStatus',
+ eventClassKey='openstackServerStatus',
serverStatus=server.status,
))
@@ -177,7 +187,7 @@ def printJSON(self):
data = dict(
events=[dict(
severity=5,
- summary='OpenStack failure: {0}'.format(ex),
+ summary='OpenStack failure: %s' % ex,
eventKey='openStackFailure',
eventClassKey='openStackFailure',
)]
@@ -186,15 +196,18 @@ def printJSON(self):
print json.dumps(data)
if __name__ == '__main__':
- authUrl = username = apiKey = None
+ username = api_key = project_id = auth_url = region_name = None
try:
- authUrl, username, apiKey = sys.argv[1:4]
+ username, api_key, project_id, auth_url, region_name = sys.argv[1:6]
except ValueError:
- print >> sys.stderr, "Usage: {0} <authUrl> <username> <api_key>" \
- .format(sys.argv[0])
+ print >> sys.stderr, (
+ "Usage: %s <username> <api_key> <project_id> <auth_url> "
+ "<region_name>"
+ ) % sys.argv[0]
sys.exit(1)
- poller = OpenStackPoller(authUrl, username, apiKey)
- poller.printJSON()
+ poller = OpenStackPoller(
+ username, api_key, project_id, auth_url, region_name)
+ poller.printJSON()
View
10 ZenPacks/zenoss/OpenStack/routers.py
@@ -14,17 +14,19 @@
from Products.ZenUtils.Ext import DirectRouter, DirectResponse
from Products import Zuul
+
class OpenStackRouter(DirectRouter):
def _getFacade(self):
return Zuul.getFacade('openstack', self.context)
- def addOpenStack(self, hostname, authUrl, username, apiKey):
+ def addOpenStack(self, username, api_key, project_id, auth_url,
+ region_name=None):
+
facade = self._getFacade()
success, message = facade.addOpenStack(
- hostname, authUrl, username, apiKey)
-
+ username, api_key, project_id, auth_url, region_name=region_name)
+
if success:
return DirectResponse.succeed(jobId=message)
else:
return DirectResponse.fail(message)
-
View
40 setup.py
@@ -16,7 +16,7 @@
# or saved. Do not modify them directly here.
# NB: PACKAGES is deprecated
NAME = "ZenPacks.zenoss.OpenStack"
-VERSION = "1.0.3"
+VERSION = "1.1.0"
AUTHOR = "Zenoss"
LICENSE = ""
NAMESPACE_PACKAGES = ['ZenPacks', 'ZenPacks.zenoss']
@@ -34,39 +34,39 @@
import subprocess
p = subprocess.Popen('make build', shell=True)
if p.poll() == None:
- p.wait()
+ p.wait()
if p.returncode != 0:
raise Exception('make exited with an error: %s' % p.returncode)
setup(
# This ZenPack metadata should usually be edited with the Zenoss
# ZenPack edit page. Whenever the edit page is submitted it will
# overwrite the values below (the ones it knows about) with new values.
- name = NAME,
- version = VERSION,
- author = AUTHOR,
- license = LICENSE,
-
+ name=NAME,
+ version=VERSION,
+ author=AUTHOR,
+ license=LICENSE,
+
# This is the version spec which indicates what versions of Zenoss
# this ZenPack is compatible with
- compatZenossVers = COMPAT_ZENOSS_VERS,
-
+ compatZenossVers=COMPAT_ZENOSS_VERS,
+
# previousZenPackName is a facility for telling Zenoss that the name
# of this ZenPack has changed. If no ZenPack with the current name is
# installed then a zenpack of this name if installed will be upgraded.
- prevZenPackName = PREV_ZENPACK_NAME,
-
+ prevZenPackName=PREV_ZENPACK_NAME,
+
# Indicate to setuptools which namespace packages the zenpack
# participates in
- namespace_packages = NAMESPACE_PACKAGES,
-
+ namespace_packages=NAMESPACE_PACKAGES,
+
# Tell setuptools what packages this zenpack provides.
- packages = find_packages(),
-
+ packages=find_packages(),
+
# Tell setuptools to figure out for itself which files to include
# in the binary egg when it is built.
- include_package_data = True,
-
+ include_package_data=True,
+
# The MANIFEST.in file is the recommended way of including additional files
# in your ZenPack. package_data is another.
#package_data = {}
@@ -77,14 +77,14 @@
# list, so any manual additions should be added to the end. Things will
# go poorly if this line is broken into multiple lines or modified to
# dramatically.
- install_requires = INSTALL_REQUIRES,
+ install_requires=INSTALL_REQUIRES,
# Every ZenPack egg must define exactly one zenoss.zenpacks entry point
# of this form.
- entry_points = {
+ entry_points={
'zenoss.zenpacks': '%s = %s' % (NAME, NAME),
},
# All ZenPack eggs must be installed in unzipped form.
- zip_safe = False,
+ zip_safe=False,
)

0 comments on commit 71669de

Please sign in to comment.
Something went wrong with that request. Please try again.