Add support to create/delete Datasource

This commit adds the support to create and delete
datasources through UI

Partially-Implements blueprint enhance-congress-dashboard
Change-Id: I08512ed2bdfba6d669aad966338678744e149303
This commit is contained in:
Anusha Ramineni 2017-05-12 11:03:48 +05:30
parent 9ce12571a6
commit 209060167e
7 changed files with 209 additions and 3 deletions

View File

@ -308,3 +308,29 @@ def datasource_status_list(request, datasource_name):
LOG.exception("Failed to retrieve status for datasource %s",
datasource_name)
raise
def supported_driver_list(request):
client = congressclient(request)
try:
data = client.list_drivers()['results']
drivers = [(d['id'], d['id']) for d in data]
return drivers
except Exception:
LOG.exception("Unable to get driver list")
raise
def create_datasource(request, data):
client = congressclient(request)
datasource = client.create_datasource(data)
return datasource
def delete_datasource(request, datasource_name):
client = congressclient(request)
try:
client.delete_datasource(datasource_name)
except Exception:
LOG.exception("deleting datasource %s failed", datasource_name)
raise

View File

@ -0,0 +1,100 @@
# Copyright 2015 VMware.
#
# 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
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from congress_dashboard.api import congress
LOG = logging.getLogger(__name__)
class CreateDatasource(forms.SelfHandlingForm):
name = forms.CharField(max_length=255,
label=_("Data Source Name"),
help_text='Name of the data source')
driver = forms.ThemableChoiceField(label=_("Driver"),
help_text='Data Source driver')
description = forms.CharField(label=_("Description"),
required=False,
help_text='Data Source Description')
username = forms.CharField(
max_length=255,
label=_("UserName"),
help_text='username to connect to the driver service')
password = forms.CharField(widget=forms.PasswordInput(render_value=False),
label=_('Password'))
tenant_name = forms.CharField(max_length=255, label=_("Project Name"))
# TODO(ramineni): support adding lazy tables
# lazy_tables = forms.CharField(max_length=255, label=_("Lazy Tables"))
auth_url = forms.URLField(max_length=255, label=_("Keystone Auth URL"))
poll_time = forms.IntegerField(
label=_("Poll Interval (in seconds)"),
help_text='periodic interval congress needs to poll data')
failure_url = 'horizon:admin:datasources:index'
@classmethod
def _instantiate(cls, request, *args, **kwargs):
return cls(request, *args, **kwargs)
def __init__(self, request, *args, **kwargs):
super(CreateDatasource, self).__init__(request, *args, **kwargs)
driver_choices = [('', _("Select a Driver"))]
drivers = congress.supported_driver_list(request)
driver_choices.extend(drivers)
self.fields['driver'].choices = driver_choices
def handle(self, request, data):
datasource_name = data['name']
datasource_description = data.get('description')
datasource_driver = data.pop('driver')
config = {
'username': data['username'],
'password': data['password'],
'tenant_name': data['tenant_name'],
'auth_url': data['auth_url'],
'poll_time': data['poll_time']
}
try:
params = {
'name': datasource_name,
'driver': datasource_driver,
'description': datasource_description,
'config': config
}
datasource = congress.create_datasource(request, params)
msg = _('Created Data Source "%s"') % datasource_name
LOG.info(msg)
messages.success(request, msg)
except Exception as e:
msg_args = {'datasource_name': datasource_name, 'error': str(e)}
msg = _('Failed to create data source "%(datasource_name)s": '
'%(error)s') % msg_args
LOG.error(msg)
messages.error(self.request, msg)
redirect = reverse(self.failure_url)
raise exceptions.Http302(redirect)
return datasource

View File

@ -15,8 +15,11 @@
from django.core.urlresolvers import reverse
from django.template.defaultfilters import unordered_list
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from horizon import tables
from congress_dashboard.api import congress
def get_resource_url(obj):
return reverse('horizon:admin:datasources:datasource_table_detail',
@ -40,7 +43,37 @@ class DataSourceRowsTable(tables.DataTable):
hidden_title = False
# TODO(ramineni): support create/delete datasource
class CreateDatasource(tables.LinkAction):
name = 'create_datasource'
verbose_name = _('Create Data Source')
url = 'horizon:admin:datasources:create'
classes = ('ajax-modal',)
icon = 'plus'
class DeleteDatasource(tables.DeleteAction):
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Delete Data Source",
u'Deleted Data Sources',
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u'Deleted Data Source',
u'Deleted Data Sources',
count
)
redirect_url = 'horizon:admin:datasources:index'
def delete(self, request, name):
congress.delete_datasource(request, name)
class DataSourcesTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Data Source Name"),
link='horizon:admin:datasources:datasource_detail')
@ -52,8 +85,8 @@ class DataSourcesTable(tables.DataTable):
name = "datasources_list"
verbose_name = _("Data Sources")
hidden_title = False
# table_actions = (CreateDatasource,)
# row_actions = (Disable,)
table_actions = (CreateDatasource, DeleteDatasource)
row_actions = (DeleteDatasource, )
class DataSourceStatusesTable(tables.DataTable):

View File

@ -0,0 +1,26 @@
{% extends "horizon/common/_modal_form.html" %}
{% load i18n %}
{% load url from future %}
{% block form_id %}create_datasource_form{% endblock %}
{% block form_action %}{% url 'horizon:admin:datasources:create' %}{% endblock %}
{% block modal_id %}create_datasource_modal{% endblock %}
{% block modal-header %}{% trans "Create Data Source" %}{% endblock %}
{% block modal-body %}
<div class="left">
<fieldset>
{% include "horizon/common/_form_fields.html" %}
</fieldset>
</div>
<div class="right">
<h3>{% trans "Description:" %}</h3>
<p>{% trans "Create a new data source with the any of the supported drivers listed."%}</p>
<p>{% trans "Congress uses a driver to connect each service to the policy engine. Connection details such as username, password, auth_url, project_name needed for congress to connect to respective service to be able poll data."%}</p>
</div>
{% endblock %}
{% block modal-footer %}
<input class="btn btn-primary pull-right" type="submit" value="{% trans "Create Data Source" %}" />
<a href="{% url 'horizon:admin:datasources:index' %}" class="btn btn-default secondary cancel close">{% trans "Cancel" %}</a>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Create Data Source" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("Create Data Source") %}
{% endblock page_header %}
{% block main %}
{% include "admin/datasources/_create.html" %}
{% endblock %}

View File

@ -26,6 +26,7 @@ DATASOURCE = r'^(?P<datasource_id>[^/]+)/%s$'
urlpatterns = patterns(
'',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(SERVICES % 'detail', views.DetailView.as_view(),
name='datasource_table_detail'),
url(DATASOURCE % 'detail', views.DatasourceView.as_view(),

View File

@ -16,13 +16,16 @@ import copy
import logging
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon import tables
from congress_dashboard.api import congress
from congress_dashboard.datasources import forms as datasource_forms
from congress_dashboard.datasources import tables as datasources_tables
@ -107,6 +110,12 @@ class DatasourceView(tables.DataTableView):
return []
class CreateView(forms.ModalFormView):
form_class = datasource_forms.CreateDatasource
template_name = 'admin/datasources/create.html'
success_url = reverse_lazy('horizon:admin:datasources:index')
class DetailView(tables.DataTableView):
"""List details about and rows from a data source (service or policy)."""
table_class = datasources_tables.DataSourceRowsTable