Profiles UI with extended types and CDN
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/613e4ba6 Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/613e4ba6 Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/613e4ba6 Branch: refs/heads/master Commit: 613e4ba6c49404d38440800e01a8535af984d344 Parents: 8cf46ac Author: Jan van Doorn <jan_vando...@cable.comcast.com> Authored: Mon Jan 2 13:44:49 2017 -0700 Committer: Jan van Doorn <j...@apache.org> Committed: Fri Feb 17 17:49:10 2017 +0000 ---------------------------------------------------------------------- .../20161226000000_cdn_domain_name.sql | 22 +++++--- traffic_ops/app/lib/API/Profile.pm | 4 ++ traffic_ops/app/lib/Fixtures/Profile.pm | 7 +++ traffic_ops/app/lib/MojoPlugins/Enum.pm | 44 +++++++++++++++ traffic_ops/app/lib/UI/Cdn.pm | 6 +-- traffic_ops/app/lib/UI/DeliveryService.pm | 7 ++- traffic_ops/app/lib/UI/Profile.pm | 57 ++++++++++++++++++-- traffic_ops/app/templates/profile/_form.html.ep | 17 +++++- traffic_ops/app/templates/profile/index.html.ep | 2 + traffic_ops/app/templates/profile/view.html.ep | 8 +++ 10 files changed, 158 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/db/migrations/20161226000000_cdn_domain_name.sql ---------------------------------------------------------------------- diff --git a/traffic_ops/app/db/migrations/20161226000000_cdn_domain_name.sql b/traffic_ops/app/db/migrations/20161226000000_cdn_domain_name.sql index 22e855a..d7e0d8c 100644 --- a/traffic_ops/app/db/migrations/20161226000000_cdn_domain_name.sql +++ b/traffic_ops/app/db/migrations/20161226000000_cdn_domain_name.sql @@ -16,13 +16,23 @@ -- +goose Up -- SQL in section 'Up' is executed when this migration is applied --- INSERT INTO TYPE (name, description, use_in_table) VALUES ('SERVER_PROFILE', 'Profile to be assigned to server', 'profile'); --- INSERT INTO TYPE (name, description, use_in_table) VALUES ('DS_PROFILE', 'Profile to be assigned to deliveryservice', 'profile'); --- better to use ENUMs, I think - -CREATE TYPE profile_type AS ENUM ('SERVER_PROFILE', 'DS_PROFILE'); +CREATE TYPE profile_type AS ENUM ('ATS_PROFILE', 'TR_PROFILE', 'TM_PROFILE', 'TS_PROFILE', 'TP_PROFILE', 'INFLUXDB_PROFILE', + 'RIAK_PROFILE', 'SPLUNK_PROFILE', 'DS_PROFILE', 'ORG_PROFILE', 'KAFKA_PROFILE', 'LOGSTASH_PROFILE', 'ES_PROFILE', 'UNK_PROFILE'); ALTER TABLE public.profile ADD COLUMN type profile_type; -UPDATE public.profile SET type='SERVER_PROFILE'; +UPDATE public.profile SET type='UNK_PROFILE'; -- So we don't get any NULL, these should be checked. +UPDATE public.profile SET type='TR_PROFILE' WHERE name like 'CCR_%' OR name like 'TR_%'; +UPDATE public.profile SET type='TM_PROFILE' WHERE name like 'RASCAL_%' OR name like 'TM_%'; +UPDATE public.profile SET type='TS_PROFILE' WHERE name like 'TRAFFIC_STATS%'; +UPDATE public.profile SET type='TP_PROFILE' WHERE name like 'TRAFFIC_PORTAL%'; +UPDATE public.profile SET type='INFLUXDB_PROFILE' WHERE name like 'INFLUXDB%'; +UPDATE public.profile SET type='RIAK_PROFILE' WHERE name like 'RIAK%'; +UPDATE public.profile SET type='SPLUNK_PROFILE' WHERE name like 'SPLUNK%'; +UPDATE public.profile SET type='ORG_PROFILE' WHERE name like '%ORG%' or name like 'MSO%' or name like '%ORIGIN%'; +UPDATE public.profile SET type='KAFKA_PROFILE' WHERE name like 'KAFKA%'; +UPDATE public.profile SET type='LOGSTASH_PROFILE' WHERE name like 'LOGSTASH_%'; +UPDATE public.profile SET type='ES_PROFILE' WHERE name like 'ELASTICSEARCH%'; +UPDATE public.profile SET type='ATS_PROFILE' WHERE name like 'EDGE%' or name like 'MID%'; + ALTER TABLE public.profile ALTER type SET NOT NULL; ALTER TABLE public.cdn ADD COLUMN domain_name text; http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/API/Profile.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/API/Profile.pm b/traffic_ops/app/lib/API/Profile.pm index b41b835..1de9c8c 100644 --- a/traffic_ops/app/lib/API/Profile.pm +++ b/traffic_ops/app/lib/API/Profile.pm @@ -37,6 +37,8 @@ sub index { "id" => $row->profile->id, "name" => $row->profile->name, "description" => $row->profile->description, + "cdn" => $row->profile->cdn, + "type" => $row->profile->type, "lastUpdated" => $row->profile->last_updated } ); @@ -49,6 +51,8 @@ sub index { "id" => $row->id, "name" => $row->name, "description" => $row->description, + "cdn" => defined($row->cdn) ? $row->cdn->name : "-", + "type" => $row->type, "lastUpdated" => $row->last_updated } ); http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/Fixtures/Profile.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/Fixtures/Profile.pm b/traffic_ops/app/lib/Fixtures/Profile.pm index be05f9c..f4370fd 100644 --- a/traffic_ops/app/lib/Fixtures/Profile.pm +++ b/traffic_ops/app/lib/Fixtures/Profile.pm @@ -25,6 +25,7 @@ my %definition_for = ( name => 'EDGE1', description => 'edge description', cdn => 1, + type => 'SERVER_PROFILE', }, }, MID1 => { @@ -34,6 +35,7 @@ my %definition_for = ( name => 'MID1', description => 'mid description', cdn => 1, + type => 'SERVER_PROFILE', }, }, CCR1 => { @@ -43,6 +45,7 @@ my %definition_for = ( name => 'CCR1', description => 'ccr description', cdn => 1, + type => 'SERVER_PROFILE', }, }, CCR2 => { @@ -52,6 +55,7 @@ my %definition_for = ( name => 'CCR2', description => 'ccr description', cdn => 2, + type => 'SERVER_PROFILE', }, }, RIAK1 => { @@ -61,6 +65,7 @@ my %definition_for = ( name => 'RIAK1', description => 'riak description', cdn => 1, + type => 'SERVER_PROFILE', }, }, RASCAL1 => { @@ -70,6 +75,7 @@ my %definition_for = ( name => 'RASCAL1', description => 'rascal description', cdn => 1, + type => 'SERVER_PROFILE', }, }, RASCAL2 => { @@ -79,6 +85,7 @@ my %definition_for = ( name => 'RASCAL2', description => 'rascal2 description', cdn => 2, + type => 'SERVER_PROFILE', }, }, MISC => { http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/MojoPlugins/Enum.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/MojoPlugins/Enum.pm b/traffic_ops/app/lib/MojoPlugins/Enum.pm new file mode 100644 index 0000000..b132b61 --- /dev/null +++ b/traffic_ops/app/lib/MojoPlugins/Enum.pm @@ -0,0 +1,44 @@ +package MojoPlugins::Enum; +# +# +# 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. +# +# +# + +use Mojo::Base 'Mojolicious::Plugin'; + +sub register { + my ( $self, $app, $conf ) = @_; + + $app->renderer->add_helper( + + # Returns an array with the possible values for the enum. + # Note that for now this is postgres specific; if we need to support other databases, we need to add support here. + enum_values => sub { + my $self = shift; + my $enum_name = shift; + + my @possible; + my $dbh = Schema->database_handle; + my $h = $dbh->prepare('SELECT unnest(enum_range(NULL:: ' . $enum_name . ' )) as value ORDER BY value'); + $h->execute || print "ERR"; + while ( my @data = $h->fetchrow_array() ) { + push(@possible, $data[0]); + } + return \@possible; + } + ); +} + +1; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/UI/Cdn.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/UI/Cdn.pm b/traffic_ops/app/lib/UI/Cdn.pm index f36bd07..3f2f160 100644 --- a/traffic_ops/app/lib/UI/Cdn.pm +++ b/traffic_ops/app/lib/UI/Cdn.pm @@ -693,11 +693,11 @@ sub aprofile { my $self = shift; my %data = ( "aaData" => [] ); - my $rs = $self->db->resultset('Profile')->search(undef); + my $rs = $self->db->resultset('Profile')->search(undef, { prefetch => ['cdn'] } ); while ( my $row = $rs->next ) { - - my @line = [ $row->id, $row->name, $row->name, $row->description, $row->last_updated ]; + my $ctext = defined( $row->cdn ) ? $row->cdn->name : "-"; + my @line = [ $row->id, $row->name, $row->name, $row->description, $row->type, $ctext, $row->last_updated ]; push( @{ $data{'aaData'} }, @line ); } $self->render( json => \%data ); http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/UI/DeliveryService.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/UI/DeliveryService.pm b/traffic_ops/app/lib/UI/DeliveryService.pm index b40caa3..069175e 100644 --- a/traffic_ops/app/lib/UI/DeliveryService.pm +++ b/traffic_ops/app/lib/UI/DeliveryService.pm @@ -45,9 +45,12 @@ sub edit { my $self = shift; my $id = $self->param('id'); - my $rs_ds = - $self->db->resultset('Deliveryservice')->search( { 'me.id' => $id }, { prefetch => [ 'cdn', { 'type' => undef }, { 'profile' => undef } ] } ); + my $rs_ds = $self->db->resultset('Deliveryservice')->search( { 'me.id' => $id }, { prefetch => [ 'cdn', 'type', 'profile' ] } ); my $data = $rs_ds->single; + print Dumper($data); + if (!defined($data->profile)) { + $data->profile(-1); + } my $action; my $regexp_set = &get_regexp_set( $self, $id ); my $cdn_domain = $self->get_cdn_domain_by_ds_id($id); http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/lib/UI/Profile.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/UI/Profile.pm b/traffic_ops/app/lib/UI/Profile.pm index 2966750..e386341 100644 --- a/traffic_ops/app/lib/UI/Profile.pm +++ b/traffic_ops/app/lib/UI/Profile.pm @@ -31,10 +31,46 @@ sub index { $self->stash( profile => {} ); } +sub stash_cdn_selector { + my $self = shift; + my $selected = shift || -1; + + my $rs = $self->db->resultset('Cdn')->search(undef); + my @cdns; + while ( my $row = $rs->next ) { + if ($row->id == $selected) { + push(@cdns, [ $row->name => $row->id, selected => 'true' ] ); + } else { + push(@cdns, [ $row->name => $row->id ] ); + } + } + $self->stash( cdns => \@cdns ); +} + +sub stash_profile_type_selector { + my $self = shift; + my $selected = shift || -1; + + my $enum_possible = $self->enum_values("profile_type"); + my @possible; + foreach my $val ( @{$enum_possible} ) { + if ($val eq $selected) { + push(@possible, [ $val => $val , selected => 'true' ] ); + } else { + push(@possible, [ $val => $val ] ); + } + } + $self->stash( profile_type_possible => \@possible ); +} + # for the fancybox view sub add { my $self = shift; my %profiles = get_profiles($self); + + $self->stash_cdn_selector(); + $self->stash_profile_type_selector(); + $self->stash( profile => {}, profiles => \%profiles, fbox_layout => 1 ); } @@ -43,6 +79,10 @@ sub edit { my $id = $self->param('id'); my $cursor = $self->db->resultset('Profile')->search( { id => $id } ); my $data = $cursor->single; + + $self->stash_cdn_selector($data->cdn->id); + $self->stash_profile_type_selector($data->type); + &stash_role($self); $self->stash( profile => $data, id => $data->id, fbox_layout => 1 ); return $self->render('profile/edit'); @@ -62,10 +102,9 @@ sub view { my $id = $self->param('id'); my $rs_param = $self->db->resultset('Profile')->search( { id => $id } ); + my $data = $rs_param->single; my $param_count = $self->db->resultset('ProfileParameter')->search( { profile => $id } )->count(); - # if ( $mode eq "view" ) { - my $data = $rs_param->single; $self->stash( profile => $data ); $self->stash( param_count => $param_count ); @@ -73,7 +112,6 @@ sub view { $self->stash( fbox_layout => 1 ); - # } } # Read @@ -82,12 +120,14 @@ sub readprofile { my @data; my $orderby = "name"; $orderby = $self->param('orderby') if ( defined $self->param('orderby') ); - my $rs_data = $self->db->resultset("Profile")->search( undef, { order_by => 'me.' . $orderby } ); + my $rs_data = $self->db->resultset("Profile")->search( undef, { prefetch => ['cdn'], order_by => 'me.' . $orderby } ); while ( my $row = $rs_data->next ) { push( @data, { "id" => $row->id, "name" => $row->name, + "type" => $row->type, + "cdn" => $row->cdn->name, "description" => $row->description, "last_updated" => $row->last_updated, } @@ -194,12 +234,16 @@ sub update { my $id = $self->param('id'); my $name = $self->param('profile.name'); my $description = $self->param('profile.description'); + my $cdn = $self->param('profile.cdn'); + my $type = $self->param('profile.type'); if ( $self->check_profile_input("edit") ) { my $update = $self->db->resultset('Profile')->find( { id => $id } ); $update->name($name); $update->description($description); + $update->cdn($cdn); + $update->type($type); $update->update(); # if the update has failed, we don't even get here, we go to the exception page. @@ -221,6 +265,9 @@ sub create { my $new_id = -1; my $p_name = $self->param('profile.name'); my $p_desc = $self->param('profile.description'); + my $p_cdn = $self->param('profile.cdn'); + my $p_type = $self->param('profile.type'); + if ( !&is_admin($self) ) { my $err = "You must be an ADMIN to perform this operation!" . "__NEWLINE__"; return $self->flash( message => $err ); @@ -230,6 +277,8 @@ sub create { { name => $p_name, description => $p_desc, + cdn => $p_cdn, + type => $p_type, } ); $insert->insert(); http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/templates/profile/_form.html.ep ---------------------------------------------------------------------- diff --git a/traffic_ops/app/templates/profile/_form.html.ep b/traffic_ops/app/templates/profile/_form.html.ep index 5073c43..3301d37 100644 --- a/traffic_ops/app/templates/profile/_form.html.ep +++ b/traffic_ops/app/templates/profile/_form.html.ep @@ -26,4 +26,19 @@ <% } %> %= label_for 'description' => '* Description', class => 'label' %= field('profile.description')->text(class => 'field', required=> 'required') -</div><br> +</div> +<br> +<div class="block"> + <% unless (field('profile.cdn')->valid) { %> + <span class="field-with-error"><%= field('profile.cdn')->error %></span> + <% } %> + %= label_for 'profile.cdn' => '* CDN', class => 'label' + %= field('profile.cdn')->select( \@{$cdns} ) +</div> +<div class="block"> + <% unless (field('profile.type')->valid) { %> + <span class="field-with-error"><%= field('profile.type')->error %></span> + <% } %> + %= label_for 'profile.type' => '* Profile Type', class => 'label' + %= field('profile.type')->select( \@{$profile_type_possible} ) +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/templates/profile/index.html.ep ---------------------------------------------------------------------- diff --git a/traffic_ops/app/templates/profile/index.html.ep b/traffic_ops/app/templates/profile/index.html.ep index 6df8688..de0e9c9 100644 --- a/traffic_ops/app/templates/profile/index.html.ep +++ b/traffic_ops/app/templates/profile/index.html.ep @@ -92,6 +92,8 @@ $("a.fancybox").fancybox({ <td></td> <td>Profile Name</td> <td>Profile Description</td> + <td>Type</td> + <td>Cdn</td> <td>Last updated</td> </tr> </thead> http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/613e4ba6/traffic_ops/app/templates/profile/view.html.ep ---------------------------------------------------------------------- diff --git a/traffic_ops/app/templates/profile/view.html.ep b/traffic_ops/app/templates/profile/view.html.ep index c24f53e..d65b646 100644 --- a/traffic_ops/app/templates/profile/view.html.ep +++ b/traffic_ops/app/templates/profile/view.html.ep @@ -63,6 +63,14 @@ function deletefunction() { <td>Description</td> <td class="editable" id="description"><%= $profile->description %></td> </tr> + <tr> + <td>CDN</td> + <td class="editable" id="cdn"><%= defined($profile->cdn) ? $profile->cdn->name : "-" %></td> + </tr> + <tr> + <td>Type</td> + <td class="editable" id="type"><%= $profile->type %></td> + </tr> </table> <div id="parameter_link"> <br>