You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by de...@apache.org on 2017/05/23 18:31:50 UTC

[1/2] incubator-trafficcontrol git commit: This closes #588

Repository: incubator-trafficcontrol
Updated Branches:
  refs/heads/master 4671f1b39 -> 90b0d26cd


This closes #588


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/90b0d26c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/90b0d26c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/90b0d26c

Branch: refs/heads/master
Commit: 90b0d26cdd7dc5591a87f9cc65afdd24895d9767
Parents: a34b783
Author: Dewayne Richardson <de...@apache.org>
Authored: Tue May 23 12:31:42 2017 -0600
Committer: Dewayne Richardson <de...@apache.org>
Committed: Tue May 23 12:31:42 2017 -0600

----------------------------------------------------------------------

----------------------------------------------------------------------



[2/2] incubator-trafficcontrol git commit: adds routes to fetch unassigned parameters for profile/cachegroup and unlink assigned parameters as well

Posted by de...@apache.org.
adds routes to fetch unassigned parameters for profile/cachegroup and unlink assigned parameters as well


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/a34b7832
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/a34b7832
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/a34b7832

Branch: refs/heads/master
Commit: a34b78325b07312b09fa7ef8917abd383122cf10
Parents: 4671f1b
Author: Jeremy Mitchell <mi...@gmail.com>
Authored: Fri May 19 09:10:14 2017 -0600
Committer: Dewayne Richardson <de...@apache.org>
Committed: Tue May 23 12:31:42 2017 -0600

----------------------------------------------------------------------
 docs/source/development/traffic_ops.rst         |   1 +
 .../traffic_ops_api/v12/cachegroup.rst          |  55 ++++++
 .../v12/cachegroup_parameter.rst                | 177 +++++++++++++++++++
 .../traffic_ops_api/v12/parameter.rst           | 109 ++++++++++++
 traffic_ops/app/lib/API/CachegroupParameter.pm  |  80 +++++++++
 traffic_ops/app/lib/API/Parameter.pm            |  69 ++++++++
 traffic_ops/app/lib/API/Profile.pm              |  32 ++++
 traffic_ops/app/lib/Fixtures/Parameter.pm       |   9 +
 .../app/lib/Fixtures/ProfileParameter.pm        |   9 +-
 traffic_ops/app/lib/TrafficOpsRoutes.pm         |   6 +
 traffic_ops/app/t/api/1.2/cachegroup.t          |  21 +++
 traffic_ops/app/t/api/1.2/profile.t             |  29 +++
 traffic_ops/app/t/api/1.2/profile_parameter.t   |   6 +-
 13 files changed, 599 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/docs/source/development/traffic_ops.rst
----------------------------------------------------------------------
diff --git a/docs/source/development/traffic_ops.rst b/docs/source/development/traffic_ops.rst
index 18b73a8..ed287b5 100644
--- a/docs/source/development/traffic_ops.rst
+++ b/docs/source/development/traffic_ops.rst
@@ -605,6 +605,7 @@ API 1.2 Reference
 
   traffic_ops_api/v12/asn
   traffic_ops_api/v12/cachegroup
+  traffic_ops_api/v12/cachegroup_parameter
   traffic_ops_api/v12/cache_stats
   traffic_ops_api/v12/cdn
   traffic_ops_api/v12/changelog

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/docs/source/development/traffic_ops_api/v12/cachegroup.rst
----------------------------------------------------------------------
diff --git a/docs/source/development/traffic_ops_api/v12/cachegroup.rst b/docs/source/development/traffic_ops_api/v12/cachegroup.rst
index bc9f775..aefc466 100644
--- a/docs/source/development/traffic_ops_api/v12/cachegroup.rst
+++ b/docs/source/development/traffic_ops_api/v12/cachegroup.rst
@@ -234,6 +234,61 @@ Cache Group
 
 |
 
+**GET /api/1.2/cachegroups/:id/unassigned_parameters**
+
+  Retrieves all parameters NOT assigned to the cache group.
+
+  Authentication Required: Yes
+
+  Role(s) Required: None
+
+  **Request Route Parameters**
+
+  +------------------+----------+-----------------------+
+  |       Name       | Required | Description           |
+  +==================+==========+=======================+
+  | ``id``           | yes      | Cache group id        |
+  +------------------+----------+-----------------------+
+
+  **Response Properties**
+
+  +------------------+---------+--------------------------------------------------------------------------------+
+  |    Parameter     |  Type   |                    Description                                                 |
+  +==================+=========+================================================================================+
+  | ``last_updated`` | string  | The Time / Date this server entry was last updated                             |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``secure``       | boolean | When true, the parameter is accessible only by admin users. Defaults to false. |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``value``        | string  | The parameter value, only visible to admin if secure is true                   |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``name``         | string  | The parameter name                                                             |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``config_file``  | string  | The parameter config_file                                                      |
+  +------------------+---------+--------------------------------------------------------------------------------+
+
+  **Response Example** ::
+
+    {
+     "response": [
+        {
+           "last_updated": "2012-09-17 21:41:22",
+           "secure": false,
+           "value": "0,1,2,3,4,5,6",
+           "name": "Drive_Letters",
+           "config_file": "storage.config"
+        },
+        {
+           "last_updated": "2012-09-17 21:41:22",
+           "secure": true,
+           "value": "STRING __HOSTNAME__",
+           "name": "CONFIG proxy.config.proxy_name",
+           "config_file": "records.config"
+        }
+     ],
+    }
+
+|
+
 **GET /api/1.2/cachegroup/:parameter_id/parameter**
 
   Authentication Required: Yes

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/docs/source/development/traffic_ops_api/v12/cachegroup_parameter.rst
----------------------------------------------------------------------
diff --git a/docs/source/development/traffic_ops_api/v12/cachegroup_parameter.rst b/docs/source/development/traffic_ops_api/v12/cachegroup_parameter.rst
new file mode 100644
index 0000000..9f4d58c
--- /dev/null
+++ b/docs/source/development/traffic_ops_api/v12/cachegroup_parameter.rst
@@ -0,0 +1,177 @@
+..
+..
+.. 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.
+..
+
+.. _to-api-v12-profileparameters:
+
+
+Cache Group parameters
+======================
+
+.. _to-api-v12-cachegroupparameters-route:
+
+/api/1.2/cachegroupparameters
++++++++++++++++++++++++++++++
+
+**POST /api/1.2/cachegroupparameters**
+
+	Assign parameter(s) to cache group(s).
+
+	Authentication Required: Yes
+
+	Role(s) Required:  Admin or Operations
+
+	**Request Properties**
+
+	Two formats are acceptable.
+
+	Single cachegroup-parameter format:
+
+	+------------------+----------+----------------------------------------------------+
+	| Parameter        | Required | Description                                        |
+	+==================+==========+====================================================+
+	| ``cacheGroupId`` | yes      | cache group id.                                    |
+	+------------------+----------+----------------------------------------------------+
+	| ``parameterId``  | yes      | parameter id.                                      |
+	+------------------+----------+----------------------------------------------------+
+
+	Profile-parameter array format:
+
+	+-----------------------+----------+----------------------------------------------------+
+	| Parameter             | Required | Description                                        |
+	+=======================+==========+====================================================+
+	|                       | yes      | cachegroup-parameter array.                        |
+	+-----------------------+----------+----------------------------------------------------+
+	| ``>cacheGroupId``     | yes      | cache group id.                                    |
+	+-----------------------+----------+----------------------------------------------------+
+	| ``>parameterId``      | yes      | parameter id.                                      |
+	+-----------------------+----------+----------------------------------------------------+
+
+  **Request Example** ::
+
+    Single cachegroup-parameter format:
+
+    {
+      "cacheGroupId": 2,
+      "parameterId": 6
+    }
+
+    Cachegroup-parameter array format:
+
+    [
+        {
+          "cacheGroupId": 2,
+          "parameterId": 6
+        },
+        {
+          "cacheGroupId": 2,
+          "parameterId": 7
+        },
+        {
+          "cacheGroupId": 3,
+          "parameterId": 6
+        }
+    ]
+
+ 	**Response Properties**
+
+	+-------------------+---------+-----------------------------------------------------+
+	|  Parameter        |  Type   |           Description                               |
+	+===================+=========+=====================================================+
+	| ``response``      | array   | Cache group-parameter associations.                 |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``>cacheGroupId`` | string  | Cache Group id.                                     |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``>parameterId``  | string  | Parameter id.                                       |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``alerts``        | array   | A collection of alert messages.                     |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``>level``        | string  | success, info, warning or error.                    |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``>text``         | string  | Alert message.                                      |
+	+-------------------+---------+-----------------------------------------------------+
+	| ``version``       | string  |                                                     |
+	+-------------------+---------+-----------------------------------------------------+
+
+  **Response Example** ::
+
+    {
+      "response":[
+        {
+          "cacheGroupId": "2",
+          "parameterId": "6"
+        },
+        {
+          "cacheGroupId": "2",
+          "parameterId": "7"
+        },
+        {
+          "cacheGroupId": "3",
+          "parameterId": "6"
+        }
+      ]
+      "alerts":[
+        {
+          "level": "success",
+          "text": "Cache group parameter associations were created."
+        }
+      ]
+    }
+
+|
+
+**DELETE /api/1.2/cachegroupparameters/{:cachegroup_id}/{:parameter_id}**
+
+    Delete a cache group parameter association.
+
+	Authentication Required: Yes
+
+	Role(s) Required:  Admin or Operations
+
+	**Request Route Parameters**
+
+	+------------------+----------+----------------------------------------------------+
+	| Name             | Required | Description                                        |
+	+==================+==========+====================================================+
+	| ``cachegroup_id``| yes      | cache group id.                                    |
+	+------------------+----------+----------------------------------------------------+
+	| ``parameter_id`` | yes      | parameter id.                                      |
+	+------------------+----------+----------------------------------------------------+
+
+ 	**Response Properties**
+
+	+-------------------+--------+-----------------------------------------------------+
+	|  Parameter        |  Type  |           Description                               |
+	+===================+========+=====================================================+
+	| ``alerts``        | array  | A collection of alert messages.                     |
+	+-------------------+--------+-----------------------------------------------------+
+	| ``>level``        | string | success, info, warning or error.                    |
+	+-------------------+--------+-----------------------------------------------------+
+	| ``>text``         | string | Alert message.                                      |
+	+-------------------+--------+-----------------------------------------------------+
+	| ``version``       | string |                                                     |
+	+-------------------+--------+-----------------------------------------------------+
+
+  **Response Example** ::
+
+    {
+      "alerts":[
+        {
+          "level": "success",
+          "text": "Cache group parameter association was deleted."
+        }
+      ]
+    }
+
+|

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/docs/source/development/traffic_ops_api/v12/parameter.rst
----------------------------------------------------------------------
diff --git a/docs/source/development/traffic_ops_api/v12/parameter.rst b/docs/source/development/traffic_ops_api/v12/parameter.rst
index 569cb85..1ee6d24 100644
--- a/docs/source/development/traffic_ops_api/v12/parameter.rst
+++ b/docs/source/development/traffic_ops_api/v12/parameter.rst
@@ -159,9 +159,118 @@ Parameter
 
 |
 
+**GET /api/1.2/parameters/:id/unassigned_profiles**
+
+    Retrieves all profiles NOT assigned to the parameter.
+
+	Authentication Required: Yes
+
+	Role(s) Required: None
+
+	**Request Route Parameters**
+
+	+---------------+----------+----------------------------------------------------+
+	|    Name       | Required |                    Description                     |
+	+===============+==========+====================================================+
+	| ``id``        |   yes    | Parameter ID.                                      |
+	+---------------+----------+----------------------------------------------------+
+
+	**Response Properties**
+
+	+-----------------+--------+----------------------------------------------------+
+	|    Parameter    |  Type  |                    Description                     |
+	+=================+========+====================================================+
+	| ``lastUpdated`` | array  | The Time / Date this server entry was last updated |
+	+-----------------+--------+----------------------------------------------------+
+	| ``name``        | string | The name for the profile                           |
+	+-----------------+--------+----------------------------------------------------+
+	| ``id``          | string | Primary key                                        |
+	+-----------------+--------+----------------------------------------------------+
+	| ``description`` | string | The description for the profile                    |
+	+-----------------+--------+----------------------------------------------------+
+
+  **Response Example** ::
+
+    {
+     "response": [
+        {
+            "lastUpdated": "2012-10-08 19:34:45",
+            "name": "CCR_TOP",
+            "id": "8",
+            "description": "Content Router for top.foobar.net"
+        }
+     ]
+    }
+
+|
+
 
 **GET /api/1.2/profiles/:id/parameters**
 
+  Retrieves all parameters assigned to the profile.
+
+  Authentication Required: Yes
+
+  Role(s) Required: None
+
+  **Request Route Parameters**
+
+  +------------------+----------+-----------------------+
+  |       Name       | Required | Description           |
+  +==================+==========+=======================+
+  | ``id``           | yes      | Profile id            |
+  +------------------+----------+-----------------------+
+
+  **Response Properties**
+
+  +------------------+---------+--------------------------------------------------------------------------------+
+  |    Parameter     |  Type   |                    Description                                                 |
+  +==================+=========+================================================================================+
+  | ``last_updated`` | string  | The Time / Date this server entry was last updated                             |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``secure``       | boolean | When true, the parameter is accessible only by admin users. Defaults to false. |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``value``        | string  | The parameter value, only visible to admin if secure is true                   |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``name``         | string  | The parameter name                                                             |
+  +------------------+---------+--------------------------------------------------------------------------------+
+  | ``config_file``  | string  | The parameter config_file                                                      |
+  +------------------+---------+--------------------------------------------------------------------------------+
+
+  **Response Example** ::
+
+    {
+     "response": [
+        {
+           "last_updated": "2012-09-17 21:41:22",
+           "secure": false,
+           "value": "foo.bar.net",
+           "name": "domain_name",
+           "config_file": "FooConfig.xml"
+        },
+        {
+           "last_updated": "2012-09-17 21:41:22",
+           "secure": false,
+           "value": "0,1,2,3,4,5,6",
+           "name": "Drive_Letters",
+           "config_file": "storage.config"
+        },
+        {
+           "last_updated": "2012-09-17 21:41:22",
+           "secure": true,
+           "value": "STRING __HOSTNAME__",
+           "name": "CONFIG proxy.config.proxy_name",
+           "config_file": "records.config"
+        }
+     ],
+    }
+
+|
+
+**GET /api/1.2/profiles/:id/unassigned_parameters**
+
+  Retrieves all parameters NOT assigned to the profile.
+
   Authentication Required: Yes
 
   Role(s) Required: None

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/lib/API/CachegroupParameter.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/API/CachegroupParameter.pm b/traffic_ops/app/lib/API/CachegroupParameter.pm
index 744bf9c..be9ae9f 100644
--- a/traffic_ops/app/lib/API/CachegroupParameter.pm
+++ b/traffic_ops/app/lib/API/CachegroupParameter.pm
@@ -37,4 +37,84 @@ sub index {
 	$self->success( { "cachegroupParameters" => \@data } );
 }
 
+sub create {
+	my $self 	= shift;
+	my $params 	= $self->req->json;
+
+	if ( !&is_oper($self) ) {
+		return $self->forbidden();
+	}
+
+	if ( !defined($params) ) {
+		return $self->alert("parameters must be in JSON format.");
+	}
+	if ( ref($params) ne 'ARRAY' ) {
+		my @temparry;
+		push(@temparry, $params);
+		$params = \@temparry;
+	}
+	if ( scalar(@{ $params }) == 0 ) {
+		return $self->alert("parameters array length is 0.");
+	}
+
+	$self->db->txn_begin();
+	foreach my $param (@{ $params }) {
+		my $cg = $self->db->resultset('Cachegroup')->find( { id => $param->{cacheGroupId} } );
+		if ( !defined($cg) ) {
+			$self->db->txn_rollback();
+			return $self->alert("Cache Group with id: " . $param->{cacheGroupId} . " doesn't exist");
+		}
+		my $parameter = $self->db->resultset('Parameter')->find( { id => $param->{parameterId} } );
+		if ( !defined($parameter) ) {
+			$self->db->txn_rollback();
+			return $self->alert("Parameter with id: " . $param->{parameterId} . " doesn't exist");
+		}
+		my $cg_param = $self->db->resultset('ProfileParameter')->find( { parameter => $parameter->id, profile => $cg->id } );
+		if ( defined($cg_param) ) {
+			$self->db->txn_rollback();
+			return $self->alert("parameter: " . $param->{parameterId} . " already associated with profile: " . $param->{profileId});
+		}
+		$self->db->resultset('CachegroupParameter')->create( { parameter => $parameter->id, cachegroup => $cg->id } )->insert();
+	}
+	$self->db->txn_commit();
+
+	&log( $self, "New cache group parameter associations were created.", "APICHANGE" );
+
+	my $response = $params;
+	return $self->success($response, "Profile parameter associations were created.");
+}
+
+sub delete {
+	my $self 			= shift;
+	my $cg_id 			= $self->param('cachegroup_id');
+	my $parameter_id 	= $self->param('parameter_id');
+
+	if ( !&is_oper($self) ) {
+		return $self->forbidden();
+	}
+
+	my $cg = $self->db->resultset('Cachegroup')->find( { id => $cg_id } );
+	if ( !defined($cg) ) {
+		return $self->not_found();
+	}
+
+	my $parameter = $self->db->resultset('Parameter')->find( { id => $parameter_id } );
+	if ( !defined($parameter) ) {
+		return $self->not_found();
+	}
+
+	my $delete = $self->db->resultset('CachegroupParameter')->find( { parameter => $parameter->id, cachegroup => $cg->id } );
+	if ( !defined($delete) ) {
+		return $self->alert("parameter: $parameter_id isn't associated with cachegroup: $cg_id.");
+	}
+
+	$delete->delete();
+
+	&log( $self, "Deleted cache group parameter " . $cg->name . " <-> " . $parameter->name, "APICHANGE" );
+
+	return $self->success_message("Profile parameter association was deleted.");
+}
+
+
+
 1;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/lib/API/Parameter.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/API/Parameter.pm b/traffic_ops/app/lib/API/Parameter.pm
index daa76b3..dd02173 100644
--- a/traffic_ops/app/lib/API/Parameter.pm
+++ b/traffic_ops/app/lib/API/Parameter.pm
@@ -107,6 +107,42 @@ sub get_profile_params {
 	$self->success( \@data );
 }
 
+sub get_profile_params_unassigned {
+    my $self         = shift;
+    my $profile_id   = $self->param('id');
+    my $profile_name = $self->param('name');
+
+    my %criteria;
+    if ( defined $profile_id ) {
+        $criteria{'profile.id'} = $profile_id;
+    } elsif ( defined $profile_name ) {
+        $criteria{'profile.name'} = $profile_name;
+    } else {
+        return $self->alert("Profile ID or Name is required");
+    }
+
+    my @assigned_params =
+        $self->db->resultset('ProfileParameter')->search( \%criteria, { prefetch => [ 'parameter', 'profile' ] } )->get_column('parameter')->all();
+
+    my $rs_data = $self->db->resultset("Parameter")->search( 'me.id' => { 'not in' => \@assigned_params } );
+    my @data = ();
+    while ( my $row = $rs_data->next ) {
+        my $value = $row->value;
+        &UI::Parameter::conceal_secure_parameter_value( $self, $row->secure, \$value );
+        push(
+            @data, {
+                "name"        => $row->name,
+                "id"          => $row->id,
+                "configFile"  => $row->config_file,
+                "value"       => $value,
+                "secure"      => \$row->secure,
+                "lastUpdated" => $row->last_updated
+            }
+        );
+    }
+    $self->success( \@data );
+}
+
 sub get_cachegroup_params {
 	my $self         = shift;
 	my $cg_id   = $self->param('id');
@@ -137,6 +173,39 @@ sub get_cachegroup_params {
 	$self->success( \@data );
 }
 
+sub get_cachegroup_params_unassigned {
+	my $self        = shift;
+	my $cg_id       = $self->param('id');
+
+	my %criteria;
+	if ( defined $cg_id ) {
+		$criteria{'cachegroup.id'} = $cg_id;
+	} else {
+        return $self->alert("Cache Group ID is required");
+    }
+
+    my @assigned_params =
+        $self->db->resultset('CachegroupParameter')->search( \%criteria, { prefetch => [ 'parameter', 'cachegroup' ] } )->get_column('parameter')->all();
+
+    my $rs_data = $self->db->resultset("Parameter")->search( 'me.id' => { 'not in' => \@assigned_params } );
+    my @data = ();
+    while ( my $row = $rs_data->next ) {
+        my $value = $row->value;
+        &UI::Parameter::conceal_secure_parameter_value( $self, $row->secure, \$value );
+        push(
+            @data, {
+                "name"        => $row->name,
+                "id"          => $row->id,
+                "configFile"  => $row->config_file,
+                "value"       => $value,
+                "secure"      => \$row->secure,
+                "lastUpdated" => $row->last_updated
+            }
+        );
+    }
+    $self->success( \@data );
+}
+
 sub create {
     my $self = shift;
     my $params = $self->req->json;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/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 2f40bc2..0396138 100644
--- a/traffic_ops/app/lib/API/Profile.pm
+++ b/traffic_ops/app/lib/API/Profile.pm
@@ -111,6 +111,38 @@ sub get_profiles_by_paramId {
 	return $self->success( \@data );
 }
 
+sub get_unassigned_profiles_by_paramId {
+	my $self    	= shift;
+	my $param_id	= $self->param('id');
+
+	my %criteria;
+	if ( defined $param_id ) {
+		$criteria{'parameter.id'} = $param_id;
+	} else {
+		return $self->alert("Parameter ID is required");
+	}
+
+	my @assigned_profiles =
+		$self->db->resultset('ProfileParameter')->search( \%criteria, { prefetch => [ 'parameter', 'profile' ] } )->get_column('profile')->all();
+
+	my $rs_data = $self->db->resultset("Profile")->search( { 'me.id' => { 'not in' => \@assigned_profiles } }, { prefetch => [ 'cdn' ] } );
+	my @data = ();
+	while ( my $row = $rs_data->next ) {
+		push(
+			@data, {
+				"id"          => $row->id,
+				"name"        => $row->name,
+				"description" => $row->description,
+				"cdn"         => defined($row->cdn) ? $row->cdn->id : undef,
+				"cdnName"     => defined($row->cdn) ? $row->cdn->name : undef,
+				"type"        => $row->type,
+				"lastUpdated" => $row->last_updated
+			}
+		);
+	}
+	$self->success( \@data );
+}
+
 sub show {
 	my $self = shift;
 	my $id   = $self->param('id');

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/lib/Fixtures/Parameter.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Fixtures/Parameter.pm b/traffic_ops/app/lib/Fixtures/Parameter.pm
index 1d645e9..8e2c0c6 100644
--- a/traffic_ops/app/lib/Fixtures/Parameter.pm
+++ b/traffic_ops/app/lib/Fixtures/Parameter.pm
@@ -560,6 +560,15 @@ my %definition_for = (
 			value       => 90,
 		},
 	},
+	'unassigned_parameter_1' => {
+		new   => 'Parameter',
+		using => {
+			id          => 65,
+			name        => 'unassigned_parameter_1',
+			config_file => 'whaterver.config',
+			value       => 852,
+		},
+	},
 );
 
 sub get_definition {

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/lib/Fixtures/ProfileParameter.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/Fixtures/ProfileParameter.pm b/traffic_ops/app/lib/Fixtures/ProfileParameter.pm
index 87cad71..01d9005 100644
--- a/traffic_ops/app/lib/Fixtures/ProfileParameter.pm
+++ b/traffic_ops/app/lib/Fixtures/ProfileParameter.pm
@@ -33,7 +33,14 @@ my %definition_for = (
             parameter => 5,
         },
     },
-    rascal_properties2 => {
+    rascal_properties3 => {
+        new   => 'ProfileParameter',
+        using => {
+            profile   => 100,
+            parameter => 6,
+        },
+    },
+    rascal_properties4 => {
         new   => 'ProfileParameter',
         using => {
             profile   => 200,

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/lib/TrafficOpsRoutes.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/app/lib/TrafficOpsRoutes.pm b/traffic_ops/app/lib/TrafficOpsRoutes.pm
index e4fa69e..ab6e5a7 100644
--- a/traffic_ops/app/lib/TrafficOpsRoutes.pm
+++ b/traffic_ops/app/lib/TrafficOpsRoutes.pm
@@ -613,6 +613,7 @@ sub api_routes {
 
 	# parameters for a profile
 	$r->get( "/api/$version/profiles/:id/parameters" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Parameter#get_profile_params', namespace => $namespace );
+	$r->get( "/api/$version/profiles/:id/unassigned_parameters" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Parameter#get_profile_params_unassigned', namespace => $namespace );
 	$r->get("/api/$version/profiles/name/:name/parameters")->over( authenticated => 1 )->to( 'Parameter#get_profile_params', namespace => $namespace );
 	$r->get( "/api/$version/parameters/profile/:name")->over( authenticated => 1 )->to( 'Parameter#get_profile_params', namespace => $namespace );
 	$r->post("/api/$version/profiles/name/:name/parameters")->over( authenticated => 1 )
@@ -628,8 +629,12 @@ sub api_routes {
 
 	# -- PARAMETERS: CACHEGROUP PARAMETERS
 	$r->get("/api/$version/cachegroups/:id/parameters" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Parameter#get_cachegroup_params', namespace => $namespace );
+	$r->get("/api/$version/cachegroups/:id/unassigned_parameters" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Parameter#get_cachegroup_params_unassigned', namespace => $namespace );
 	$r->get("/api/$version/cachegroup/:parameter_id/parameter")->over( authenticated => 1 )->to( 'Cachegroup#by_parameter_id', namespace => $namespace );
 	$r->get("/api/$version/cachegroupparameters")->over( authenticated => 1 )->to( 'CachegroupParameter#index', namespace => $namespace );
+	$r->post("/api/$version/cachegroupparameters")->over( authenticated => 1 )->to( 'CachegroupParameter#create', namespace => $namespace );
+	$r->delete("/api/$version/cachegroupparameters/:cachegroup_id/:parameter_id")->over( authenticated => 1 )
+		->to( 'CachegroupParameter#delete', namespace => $namespace );
 	$r->get("/api/$version/cachegroups/:parameter_id/parameter/available")->over( authenticated => 1 )
 		->to( 'Cachegroup#available_for_parameter', namespace => $namespace );
 
@@ -659,6 +664,7 @@ sub api_routes {
 
 	# get all profiles associated with a parameter (from profile_parameter table)
 	$r->get( "/api/$version/parameters/:id/profiles" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Profile#get_profiles_by_paramId', namespace => $namespace );
+	$r->get( "/api/$version/parameters/:id/unassigned_profiles" => [ id => qr/\d+/ ] )->over( authenticated => 1 )->to( 'Profile#get_unassigned_profiles_by_paramId', namespace => $namespace );
 
 	# -- REGIONS
 	# Supports ?orderby=key

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/t/api/1.2/cachegroup.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/cachegroup.t b/traffic_ops/app/t/api/1.2/cachegroup.t
index caa943e..7bf5d34 100644
--- a/traffic_ops/app/t/api/1.2/cachegroup.t
+++ b/traffic_ops/app/t/api/1.2/cachegroup.t
@@ -17,6 +17,7 @@ use Mojo::Base -strict;
 use Test::More;
 use Test::Mojo;
 use DBI;
+use JSON;
 use strict;
 use warnings;
 no warnings 'once';
@@ -271,6 +272,26 @@ ok $t->put_ok('/api/1.2/cachegroups/' . $cg_id . '/update' => {Accept => 'applic
         "shortName" => "cg_edge_1",
         "typeName" => "EDGE_LOC"})->status_is(404)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 
+Test::TestHelper->unload_core_data($schema);
+Test::TestHelper->load_core_data($schema);
+
+# Count the 'response number'
+my $count_response = sub {
+    my ( $t, $count ) = @_;
+    my $json = decode_json( $t->tx->res->content->asset->slurp );
+    my $r    = $json->{response};
+    return $t->success( is( scalar(@$r), $count ) );
+};
+
+# there are currently 61 parameters not assigned to cachegroup 100
+$t->get_ok('/api/1.2/cachegroups/100/unassigned_parameters')->status_is(200)->$count_response(61)
+    ->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+# there are currently 61 parameters not assigned to cachegroup 100
+$t->get_ok('/api/1.2/cachegroups/200/unassigned_parameters')->status_is(200)->$count_response(61)
+    ->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+
 ok $t->get_ok('/logout')->status_is(302)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 $dbh->disconnect();
 done_testing();

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/t/api/1.2/profile.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/profile.t b/traffic_ops/app/t/api/1.2/profile.t
index eb5c801..13d566f 100644
--- a/traffic_ops/app/t/api/1.2/profile.t
+++ b/traffic_ops/app/t/api/1.2/profile.t
@@ -17,6 +17,7 @@ use Mojo::Base -strict;
 use Test::More;
 use Test::Mojo;
 use DBI;
+use JSON;
 use strict;
 use warnings;
 no warnings 'once';
@@ -122,6 +123,34 @@ ok $t->delete_ok('/api/1.2/profiles/8')->status_is(200)->or( sub { diag $t->tx->
 
 ok $t->get_ok('/api/1.2/profiles/parameter/1' => {Accept => 'application/json'})->status_is(404);
 
+# Count the 'response number'
+my $count_response = sub {
+	my ( $t, $count ) = @_;
+	my $json = decode_json( $t->tx->res->content->asset->slurp );
+	my $r    = $json->{response};
+	return $t->success( is( scalar(@$r), $count ) );
+};
+
+# there are currently 6 parameters not assigned to profile 100
+$t->get_ok('/api/1.2/profiles/100/unassigned_parameters')->status_is(200)->$count_response(6)
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+# there are currently 4 parameters not assigned to profile 200
+$t->get_ok('/api/1.2/profiles/200/unassigned_parameters')->status_is(200)->$count_response(3)
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+# there are currently 7 profiles not assigned to parameter 4
+$t->get_ok('/api/1.2/parameters/4/unassigned_profiles')->status_is(200)->$count_response(7)
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+# there are currently 7 profiles not assigned to parameter 4
+$t->get_ok('/api/1.2/parameters/4/unassigned_profiles')->status_is(200)->$count_response(7)
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
+# there are currently 6 profiles not assigned to parameter 6
+$t->get_ok('/api/1.2/parameters/6/unassigned_profiles')->status_is(200)->$count_response(6)
+	->or( sub { diag $t->tx->res->content->asset->{content}; } );
+
 ok $t->get_ok('/logout')->status_is(302)->or( sub { diag $t->tx->res->content->asset->{content}; } );
 $dbh->disconnect();
 done_testing();

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a34b7832/traffic_ops/app/t/api/1.2/profile_parameter.t
----------------------------------------------------------------------
diff --git a/traffic_ops/app/t/api/1.2/profile_parameter.t b/traffic_ops/app/t/api/1.2/profile_parameter.t
index dd3bf83..9ef1cbc 100644
--- a/traffic_ops/app/t/api/1.2/profile_parameter.t
+++ b/traffic_ops/app/t/api/1.2/profile_parameter.t
@@ -46,7 +46,7 @@ Test::TestHelper->load_all_fixtures( Fixtures::Profile->new($schema_values) );
 ok $t->post_ok( '/login', => form => { u => Test::TestHelper::ADMIN_USER, p => Test::TestHelper::ADMIN_USER_PASSWORD } )->status_is(302)
 	->or( sub { diag $t->tx->res->content->asset->{content}; } ), 'Should login?';
 
-ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json => 
+ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json =>
         [
             {
                 "name"          => "param1",
@@ -71,7 +71,7 @@ ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'applicati
 	->json_is( "/response/parameters/1/secure" => "0" )
 		, 'Does the profile_parameters create details return?';
 
-ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json => 
+ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json =>
         [
             {
                 "name"          => "param1",
@@ -134,7 +134,7 @@ ok $t->post_ok('/api/1.2/profiles/'. $prof_id . '/parameters' => {Accept => 'app
 	->or( sub { diag $t->tx->res->content->asset->{content}; } )
 		, 'Does the profile_parameters create details return?';
 
-ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json => 
+ok $t->post_ok('/api/1.2/profiles/name/CCR1/parameters' => {Accept => 'application/json'} => json =>
         [
             {
                 "configFile"    => "configFile1",