X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=planetlab%2Fcommon%2Fadminsearch.php;h=354b17900127954f1341978ed0acfb4c5f11d626;hb=61556d062d4419b54810e4420803a219f2c44a39;hp=45a1c618914d37cbccf3f6f85ff5fad9d2ad9fd9;hpb=878ce4154f4619a5d07c780bf1f76dfd46771df4;p=plewww.git diff --git a/planetlab/common/adminsearch.php b/planetlab/common/adminsearch.php index 45a1c61..354b179 100644 --- a/planetlab/common/adminsearch.php +++ b/planetlab/common/adminsearch.php @@ -1,6 +1,8 @@ = 2 ) { - return true; +$pattern=""; +if (isset($_GET['pattern'])) { $pattern=$_GET['pattern']; } +if (isset($_POST['pattern'])) { $pattern=$_POST['pattern']; } + +$tokens=explode(" ",$pattern); +function token_filter ($t) { $t = trim($t); if (empty($t)) return false; return true; } +$tokens=array_filter($tokens, "token_filter"); + + +//////////////////// +// from a single search form, extract all tokens entered +// and then show all entities that match one of that tokens among +// persons - sites - slices - nodes +//////////////////// +function display_form ($pattern) { + if ($pattern) { + $title="Searching for $pattern"; + $visible=false; } else { - return false; + $title="Search for what"; + $visible=true; } + $toggle=new PlekitToggle("admin-search",$title,array('visible'=>$visible)); + $toggle->start(); + print <<< EOF +

+This form searches for any entry in the database +(among persons, slices, +sites and nodes) +matching a name fragment, or token.
+You can specify a space-separated list of tokens, all entries matching +any token would then get listed. +

+EOF; + print "
"; + $form=new PlekitForm ('/db/common/adminsearch.php',array()); + $form->start(); + print $form->label_html('pattern',"Enter space-separated tokens"); + print $form->text_html('pattern',$pattern); + print $form->submit_html('submit','Submit'); + $form->end(); + print "
\n"; + $toggle->end(); } -function get_and_print_site($site_array) { +// just look for *token* +function token_pattern ($token) { + return "*" . $token . "*"; +} + +// $type is e.g. 'Persons' -- $field is e.g. 'email' +function generic_search ($type,$field,$tokens) { global $api; - $sites = $api->GetSites( $site_array, array( "name", "site_id", - "url", "enabled", "node_ids", "person_ids", "date_created", - "slice_ids", "max_slivers", "max_slices", "login_base" ) ); - if ( count($sites) > 0 ) { - foreach( $sites as $site) { - $name = $site['name']; - $site_id = $site['site_id']; - $url = $site['url']; - $enabled = $site['enabled']; - $node_ids = $site['node_ids']; - $slice_ids_count = count($site['slice_ids']); - $person_ids = $site['person_ids']; - $date_created = date("M j G:i Y", $site['date_created']); - $max_slivers = $site['max_slivers']; - $max_slices = $site['max_slices']; - $login_base = $site['login_base']; - - echo "\n"; - - echo "$name\n"; - echo "(home)\n"; - echo "[ $slice_ids_count of $max_slices ]\n"; - - echo ""; - if (!$enabled) echo "Not Enabled
\n"; - //else echo "$date_created\n"; - echo "$date_created\n"; - - echo "Nodes: "; - foreach ($site['node_ids'] as $node_id) - { - echo " $node_id, "; - } - - echo "\n"; + $results=array(); + $methodname='Get'.$type; + /* + This was broken after 598e1e840b55262fd40c6d1700148e4f0b508065 change in plcapi. + We no longer generate a list of methods but let the api (php) object pass them through. + + if ( ! method_exists($api,$methodname)) { + plc_error("generic_search failed with methodname=$methodname"); + return $results; + } + */ + foreach ($tokens as $token) { + $filter=array($field=>token_pattern($token)); + $new_results = $api->$methodname($filter); + if (is_array($new_results)) { + $results = array_merge ($results, $new_results); } } + return $results; } -function get_and_print_hostname($host_array) { - global $api; - $nodes = $api->GetNodes( $host_array, array( "hostname", "node_id", - "site_id", "date_created", "last_contact", "boot_state" ) ); - if ( count ($nodes) > 0 ) { - foreach($nodes as $node) { - $hostname= $node['hostname']; - $node_id = $node['node_id']; - $boot_state= $node['boot_state']; - $last_contact = $node['last_contact']; - $date_created = date("M j G:i Y", $node['date_created']); - echo ""; - echo "$node_id "; - echo "$hostname"; - echo "$boot_state"; - if( $last_contact != NULL ) { - $last_contact_str = timeDiff($last_contact); +// $objects is e.g. a collection of persons +// then, e.g. on slice, $key='site_id' & $plural=false +// or, e.g. on person, $key='site_ids' & $plural=true +function generic_gather_related ($objects, $key, $plural) { + if ( empty ($objects)) + return array(); + // else, look for either 'site_id' or 'site_ids' in the first object + $sample=$objects[0]; + if ( array_key_exists($key,$sample)) { + $result=array(); + foreach ($objects as $object) { + if ($plural) { + $result = array_merge ($result, $object[$key]); } else { - $last_contact_str = "Never"; + $result []= $object[$key]; } - echo "$last_contact_str\n"; - echo "$date_created\n"; - echo "\n"; } + return $result; + } else { + plc_debug("gather_related failed with $key",$sample); + return array(); } - - return $nodes; } -function get_and_print_user ($user_array) { - global $api; - $persons= $api->GetPersons( $user_array, array( "person_id", "first_name", - "last_name", "email", "roles", "enabled", "date_created", - "site_ids" ) ); - - if ( count($persons) > 0 ) { - foreach($persons as $person) { - $first= $person['first_name']; - $last = $person['last_name']; - $person_id= $person['person_id']; - $email= $person['email']; - $enabled= $person['enabled']; - $roles = $person['roles']; - $role = $person['roles'][0]; - $date_created = date("M j G:i Y", $person['date_created']); - $site_ids= $person['site_ids']; - - echo "\n"; - - echo ""; - echo "$first $last"; - echo "($person_id) "; - echo "$email "; - - echo ""; - if (!$enabled) echo "Not Enabled
\n"; - //else echo "$date_created\n"; - echo "$date_created\n"; - //if (!$enabled) echo " Not Enabled "; - //else echo "$date"; - - echo " roles: "; - foreach ($person['roles'] as $role) { echo " $role, "; } - - echo "\n"; +////////// +// create link from an id, using the various global hashes +function plc_person_link ($person_id) {global $persons_hash; return l_person_obj($persons_hash[$person_id]);} +function plc_slice_link ($slice_id) {global $slices_hash; return l_slice_obj($slices_hash[$slice_id]);} +function plc_site_link ($site_id) {global $sites_hash; return l_site_obj($sites_hash[$site_id]);} +function plc_node_link ($node_id) {global $nodes_hash; return l_node_obj($nodes_hash[$node_id]);} + +global $table_options; +$table_options = array('notes_area'=>false); + +global $peers; +$peers = new Peers ($api); + +function display_persons ($persons,$visible) { + if ( ! $persons) return; + + $toggle=new PlekitToggle('persons-area',"Persons",array('visible'=>$visible)); + $toggle->start(); + + $headers=array('id'=>'int', + 'P'=>'string', + 'email'=>'string', + 'sites'=>'string', + 'slices'=>'string', + 'roles'=>'string'); + global $table_options; + global $peers; + $table=new PlekitTable('persons',$headers,1,$table_options); + $table->start(); + foreach ($persons as $person) { + $table->row_start(); + $table->cell($person['person_id']); + $peers->cell($table,$person['peer_id']); + $table->cell(l_person_obj($person)); + $table->cell(plc_vertical_table(array_map("plc_site_link",$person['site_ids']))); + $table->cell(plc_vertical_table(array_map("plc_slice_link",$person['slice_ids']))); + $table->cell(plc_vertical_table($person['roles'])); + $table->row_end(); + } + $table->end(); + $toggle->end(); +} - } - +function display_slices ($slices,$visible) { + if ( ! $slices) return; + + $toggle=new PlekitToggle('slices-area',"Slices",array('visible'=>$visible)); + $toggle->start(); + + $headers=array('id'=>'int', + 'P'=>'string', + 'name'=>'string', + 'site'=>'string', + 'persons'=>'string', + 'N'=>'string'); + global $table_options; + global $peers; + $table=new PlekitTable('slices',$headers,1,$table_options); + $table->start(); + foreach ($slices as $slice) { + $table->row_start(); + $table->cell($slice['slice_id']); + $peers->cell($table,$slice['peer_id']); + $table->cell(l_slice_obj($slice)); + global $sites_hash; + $site=$sites_hash[$slice['site_id']]; + $table->cell(l_site_obj($site)); + $table->cell(plc_vertical_table(array_map("plc_person_link",$slice['person_ids']))); + // this makes really long tables, use the slice link to see details + //$table->cell(plc_vertical_table(array_map("plc_node_link",$slice['node_ids']))); + $table->cell(count($slice['node_ids'])); + $table->row_end(); } - return $persons; + $table->end(); + $toggle->end(); } -// find person roles -$_person= $plc->person; -$_roles= $_person['role_ids']; - - -/////////////////////////////////////////////////////////////////////// -// Initially, we need a search form, and blank information after that. -// Based on the fields of the search form, we should be able to populate a lot -// of information, related to user, site, keys, -// -// from a simple domain name search, it would display the site, -// nodes -> pcu -// users grouped by role, -// from a user search, it would find, -// user info link, site, roles, etc. -// -// userquery will be one of these types: -// part of a user name, email, user_id -// part of a site name, site alias, site_id -// part of a node name, domain, node_id -// -// we should be able to return results based on these guesses. If they're -// good, we'll get hits, if nothing comes back, we won't display anything. - - -echo "
\n -
\n"; - -if( $_POST['userquery'] or $_GET['userquery']) { - if ( $_POST['userquery'] ) { - $query = $_POST['userquery']; - } else { - $query = $_GET['userquery']; +function display_sites ($sites,$visible) { + if ( ! $sites) return; + + $toggle=new PlekitToggle('sites-area',"Sites",array('visible'=>$visible)); + $toggle->start(); + + $headers=array('id'=>'int', + 'P'=>'string', + 'name'=>'string', + 'url'=>'string', + 'persons'=>'string', + 'slices'=>'string', + 'nodes'=>'string'); + global $table_options; + global $peers; + $table=new PlekitTable('sites',$headers,1,$table_options); + $table->start(); + foreach ($sites as $site) { + $table->row_start(); + $table->cell($site['site_id']); + $peers->cell($table,$site['peer_id']); + $table->cell(l_site_obj($site)); + $table->cell(href($site['url'],$site['url'])); + $table->cell(plc_vertical_table(array_map("plc_person_link",$site['person_ids']))); + $table->cell(plc_vertical_table(array_map("plc_slice_link",$site['slice_ids']))); + $table->cell(plc_vertical_table(array_map("plc_node_link",$site['node_ids']))); + $table->row_end(); } - } + $table->end(); + $toggle->end(); +} -echo "

(Separate with commas for multiple queries.)\n - \n - \n -

\n -
\n -
\n"; - -// if userquery then search based on string -if( $_POST['userquery'] or $_GET['userquery']) { - if ( $_POST['userquery'] ) { - $query = $_POST['userquery']; - } else { - $query = $_GET['userquery']; +function display_nodes ($nodes,$visible) { + if ( ! $nodes) return; + + $toggle=new PlekitToggle('nodes-area',"Nodes",array('visible'=>$visible)); + $toggle->start(); + + $headers=array('id'=>'int', + 'P'=>'string', + 'hostname'=>'string', + 'site'=>'string', + 'slices'=>'string'); + global $table_options; + global $peers; + $table=new PlekitTable('nodes',$headers,1,$table_options); + $table->start(); + foreach ($nodes as $node) { + $table->row_start(); + $table->cell($node['node_id']); + $peers->cell($table,$node['peer_id']); + $table->cell(l_node_obj($node)); + global $sites_hash; + $site=$sites_hash[$node['site_id']]; + $table->cell(l_site_obj($site)); + // same as above, too many entries, just list how many there are + //$table->cell(plc_vertical_table(array_map("plc_slice_link",$node['slice_ids']))); + $table->cell(count($node['slice_ids'])); + $table->row_end(); } - echo "\n"; - - $f_commas = explode(",", $query); - // PHASE 1: query contains email, user_id, or part of a user name - foreach($f_commas as $tok) { - $tok = trim($tok); // strip white space. - - $e = false; - //find user by email - if ( is_valid_email_addr($tok) ){ - $u = get_and_print_user(array("email"=>$tok)); - $e = true; - if( count( $u ) == 0 ) $none = 1; - } - $n = false; - // find user by user_id - if ( is_numeric($tok) ){ - $u = get_and_print_user(array("person_id"=>intval($tok))); - $n = true; - if( count( $u ) == 0 ) $none = 1; - } - // neither of the above, - if (!$n && !$e) { - // split on spaces, and search each part. - // TODO: search upper and lower-case - $f_spaces = explode(" ", $tok); - foreach($f_spaces as $stok) { - // assume $tok is part of a name - // get_user - $a = get_and_print_user(array("first_name"=>$stok)); - $b = get_and_print_user(array("last_name"=>$stok)); - // c = intersect_users(a, b) - // if c - // print_user(c), - // else - // print_user(a,b) - } - if( count( $a ) == 0 && count( $b ) == 0 ) $none = 1; - } + $table->end(); + $toggle->end(); +} - // PHASE 2: query contains login_base, site_id, or part of a site name - // find site by login_base - $lb = false; - $s = get_and_print_site(array("login_base"=>strtolower($tok))); - if( count( $s ) == 0 ) $none = 1; - else $lb = true; +//////////////////////////////////////////////////////////// +display_form($pattern); - $n = false; - // find site by site_id - if ( is_numeric($tok) ){ - $s = get_and_print_site(array("site_id"=>intval($tok))); - $n = true; - if( count( $s ) == 0 ) $none = 1; - } +if ($pattern) { - if( !$lb && !$n ) { - $f_spaces = explode(" ", $tok); - foreach($f_spaces as $stok) { - $a = get_and_print_site(array("name"=>$stok)); - } - if( count($a) == 0 ) $none = 1; - } + ////////// search database + // search persons on email + $persons = array(); + $persons = array_merge ($persons, generic_search ('Persons','email',$tokens)); - // PHASE 3: query contains part of a node name, domain, node_id + // search slices on name + $slices=array(); + $slices = array_merge ($slices, generic_search ('Slices','name',$tokens)); - //if( $none == 1 ) echo "\n"; - if ( is_possible_domainname($tok) ) { - $n = get_and_print_hostname(array("hostname"=>$tok)); - } + // search sites on name and login_base + $sites=array(); + $sites = array_merge ($sites, generic_search('Sites','name',$tokens)); + $sites = array_merge ($sites, generic_search('Sites','login_base',$tokens)); + + // nodes on hostname + $nodes=array(); + $nodes = array_merge ($nodes, generic_search('Nodes','hostname',$tokens)); + + print "Search results for $pattern \n"; + + // what kind of result have we gotten: + // if none : display message and exit + // if only one kind of objects : start toggle with visible=true + // otherwise start all toggles with visible=false + $areas=0; + if ($persons) $areas += 1; + if ($slices) $areas += 1; + if ($sites) $areas += 1; + if ($nodes) $areas += 1; + + if ( $areas == 0) { + plc_warning ("No result found"); + return; + } else if ($areas == 1) { + $visible=true; + } else { + $visible=false; } - echo "
Search Results:
No Results.
\n"; - } + -if (false) { - // if a site_id is given, display the site nodes only - if( $_GET['site_id'] ) { - $site_id= $_GET['site_id']; + ////////// collect all related objects + $rel_person_ids = array(); + $rel_person_ids = array_merge($rel_person_ids, generic_gather_related ($sites,'person_ids',true)); + $rel_person_ids = array_merge($rel_person_ids, generic_gather_related ($slices,'person_ids',true)); - // Get site info - $site_info= $api->GetSites( array( intval( $site_id ) ), array( "name", "person_ids" ) ); + $rel_slice_ids = array(); + $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($persons,'slice_ids',true)); + $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($sites,'slice_ids',true)); + $rel_slice_ids = array_merge($rel_slice_ids, generic_gather_related ($nodes,'slice_ids',true)); - // Get site nodes - $persons= $api->GetPersons( $site_info[0]['person_ids'], array( "person_id", "first_name", "last_name", "email", "roles", "peer_id", "enabled" ) ); - - drupal_set_title("People with " . $site_info[0]['name']); + $rel_site_ids = array(); + $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($persons,'site_ids',true)); + $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($slices,'site_id',false)); + $rel_site_ids = array_merge ( $rel_site_ids, generic_gather_related ($nodes,'site_id',false)); - sort_persons( $persons ); + $rel_node_ids = array(); + $rel_node_ids = array_merge($rel_node_ids, generic_gather_related ($sites,'node_ids',true)); + $rel_node_ids = array_merge($rel_node_ids, generic_gather_related ($slices,'node_ids',true)); - echo paginate_trash ( $persons, "person_id", "Persons", 25, "email" ); - } - // if no person id, display list of persons to choose - elseif( !$_GET['id'] ) { - - // GetPersons API call - $persons= $api->GetPersons( NULL, array( "person_id", "first_name", "last_name", "email", "roles" , "peer_id", "enabled" ) ); - - sort_persons( $persons ); - - echo "
\n -
\n"; - if( $pers_email ) echo "'$pers_email' is not a valid person email.\n"; - echo "

\n - \n - \n -

\n -
\n"; - } else { - // get the person_id from the URL - $person_id= intval( $_GET['id'] ); - - // GetPersons API call for this person - $person_info= $api->GetPersons( array( $person_id ) ); - - if( empty( $person_info ) ) { - echo "No such person."; - - } else { - // vars from api - $first_name= $person_info[0]['first_name']; - $last_name= $person_info[0]['last_name']; - $title= $person_info[0]['title']; - $url= $person_info[0]['url']; - $phone= $person_info[0]['phone']; - $email= $person_info[0]['email']; - $enabled= $person_info[0]['enabled']; - $peer_id=$person_info[0]['peer_id']; - - // arrays from api - $role_ids= $person_info[0]['role_ids']; - $roles= $person_info[0]['roles']; - $site_ids= $person_info[0]['site_ids']; - $slice_ids= $person_info[0]['slice_ids']; - $key_ids= $person_info[0]['key_ids']; - - // gets more data from API calls - $site_info= $api->GetSites( $site_ids, array( "site_id", "name" ) ); - $slice_info= $api->GetSlices( $slice_ids, array( "slice_id", "name" ) ); - $key_info= $api->GetKeys( $key_ids ); - - drupal_set_title("$first_name $last_name Account Information"); - - // start form - if ( ! $peer_id ) { - echo "\n"; - } else { - echo "
"; - } - echo "\n"; - - if ( ! $peer_id ) { -# if ( Admin, PI, or user ) allow deletion - if( in_array( 10, $_roles ) || - ( in_array( 20, $_roles ) && in_array( $site_ids[0], $_person['site_ids'] ) ) || - $_person['person_id'] == $person_id) { - - // list to take person action - echo "

\n"; - -# if ( Admin or PI ) check whether to allow # 'enabling/disabling'. - if( in_array( 10, $_roles ) || - ( in_array( 20, $_roles ) && in_array( $site_ids[0], $_person['site_ids'] ) ) ) { - - if( $enabled == true ) { - $actions['disable']= "Disable $first_name"; - } else { - $actions['enable']= "Enable $first_name"; - $select_end = $select_end . "   ". - "<- This user is not enabled. Choose here to enable or delete."; - } - if ( in_array( 10, $_roles )) { - $actions['su'] = "Become $first_name"; - } - } - -# for all cases, list each 'select' key - foreach( $actions as $key => $val ) { - echo "

\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "
First Name: $first_name
Last Name: $last_name
Title: $title
Email: $email
Password: ***********
Phone: $phone
URL: $url
\n"; - - if( in_array( 10, $_roles ) || $_person['person_id'] == $person_id ) - echo "
Update account information\n"; - - echo "


\n"; - - // keys - $can_manage_keys = ( ( ! $peer_id ) && (in_array( "10", $_roles ) || $person_id == $_person['person_id'])); - echo "

Keys

\n"; - if( !empty( $key_ids ) ) { - echo "

\n"; - echo "\n"; - - foreach( $key_info as $key ) { - $key_type= $key['key_type']; - $key_id= $key['key_id']; - $key_html= wordwrap( $key['key'], 70, "
\n", 1 ); - echo "\n"; - } - - echo "
TypeKey
$key_type$key_html
\n"; - - - } else { - echo " This user has no known key"; - } - - if( $can_manage_keys ) - echo "

Manage Keys\n"; - echo "


"; - - - // sites - echo "

Sites

\n"; - if( !empty( $site_info ) ) { - echo "\n"; - - foreach( $site_info as $site ) { - $site_name= $site['name']; - $site_id= $site['site_id']; - - echo "\n"; - } - echo "
$site_name ( remove)
\n"; - echo "\n"; - - } else { - echo " This user is not affiliated with a site !!"; - } - - // diplay site select list to add another site for user - if( ! $peer_id && in_array( 10, $_roles ) ) { - // get site info - $full_site_info= $api->GetSites( NULL, array( "site_id", "name" ) ); - - if( $site_info ) - $person_site= arr_diff( $full_site_info, $site_info ); - else - $person_site= $full_site_info; - - sort_sites( $person_site ); - - echo "

Select a site to add this user to: "; - echo ""; - - } - echo "


\n"; - - // roles - echo "

Roles

\n"; - echo "

\n"; - echo ""; - if( in_array( "10", $_roles ) ) - echo ""; - echo "\n"; - - // construct role array - for( $n=0; $n$role_ids[$n], 'name'=>$roles[$n] ); - } - - - if ( !empty ($roles) ) { - foreach( $proles as $role ) { - $role_name= $role['name']; - $role_id= $role['role_id']; - - echo "\n"; - } - } else { - echo " This user has no known role !!"; - } - - echo "
RoleRemove
$role_name"; - - - if( in_array( 10, $_roles ) ) { - echo ""; - - } - - echo "
\n"; - - if ( in_array( 10, $_roles ) ) - echo "
\n"; - - - - // if admin show roles to add - if( in_array( 10, $_roles ) ) { - $all_roles= $api->GetRoles(); - $addable_roles= arr_diff( $all_roles, $proles ); - - if( !empty( $addable_roles ) ) { - echo "

Add role: \n"; - - } - } - - echo "


\n"; - - // slices - echo "

Slices

\n"; - if( !empty( $slice_info ) ) { - - foreach( $slice_info as $slice ) { - $slice_name= $slice['name']; - $slice_id= $slice['slice_id']; - - echo "$slice_name
\n"; - } - - } else { - echo "No slices found for that user"; - } + ////////// fetch related and store in a global hash + $rel_persons = $api->GetPersons ($rel_person_ids); + global $persons_hash; $persons_hash=array(); + foreach ($rel_persons as $person) $persons_hash[$person['person_id']]=$person; - if ( ! $peer_id ) { - echo "\n"; - } else { - echo "
\n"; - } + $rel_slices = $api->GetSlices ($rel_slice_ids); + global $slices_hash; $slices_hash=array(); + foreach ($rel_slices as $slice) $slices_hash[$slice['slice_id']]=$slice; - } - echo "

Back to person list"; + $rel_sites = $api->GetSites ($rel_site_ids); + global $sites_hash; $sites_hash=array(); + foreach ($rel_sites as $site) $sites_hash[$site['site_id']]=$site; - } - } + $rel_nodes = $api->GetNodes ($rel_node_ids); + global $nodes_hash; $nodes_hash=array(); + foreach ($rel_nodes as $node) $nodes_hash[$node['node_id']]=$node; + + ////////// show results + display_persons ($persons,$visible); + display_slices ($slices,$visible); + display_sites($sites,$visible); + display_nodes($nodes,$visible); + } // Print footer include 'plc_footer.php';