1 = Resources = 2 3 In imip-agent, resources are a special kind of user that act upon requests 4 to schedule events and that perform such scheduling autonomously, meaning 5 that no human intervention is necessary when such resources receive messages 6 containing invitations. 7 8 By default, the [[../AgentPrograms|agent program]] responsible for resources 9 merely attempts to fit a received event into the resource's schedule. However, 10 in some organisations and environments, it is likely to be the case that other 11 policies are needed to ensure that a resource is not misused, overused or made 12 unnecessarily unavailable. 13 14 The [[../Preferences|preferences]] provide a way of controlling the behaviour 15 of resources, just as with any other kind of user, but certain preferences 16 are central to the configuration of resources. 17 18 <<TableOfContents(2,4)>> 19 20 == Confirmation and Retraction Functions == 21 22 Confirmation and retraction functions are used to update other resources and 23 systems with the details of scheduled events. When an event is successfully 24 scheduled (according to the scheduling functions), all registered confirmation 25 functions are invoked to perform such notifications. Similarly, when an event 26 is cancelled, all registered retraction functions are invoked to inform other 27 components of the removal of the event from schedules. 28 29 The [[../Preferences#confirmation_function|confirmation_function]] and 30 [[../Preferences#retraction_function|retraction_function]] settings indicate 31 the behaviour of a resource when such circumstances arise. By themselves, 32 these settings do no more than keep a kind of journal of scheduling events, 33 but certain scheduling functions may build upon such journals to make 34 scheduling decisions. For example: 35 36 {{{{#!table 37 '''All Functions''' || '''Decision Process''' 38 == 39 <style="vertical-align: top;"> 40 41 Scheduling functions: 42 43 {{{ 44 check_quota 45 }}} 46 47 Confirmation functions: 48 49 {{{ 50 add_to_quota 51 }}} 52 53 Retraction functions: 54 55 {{{ 56 remove_from_quota 57 }}} 58 59 || 60 61 {{{#!graphviz 62 //format=svg 63 //transform=notugly 64 digraph scheduling_decisions { 65 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 66 edge [tooltip="Scheduling decisions"]; 67 68 subgraph { 69 rank=same; 70 mail [label="Incoming mail\nfrom vincent.vole@example.com",shape=folder,style=filled,fillcolor=cyan]; 71 cancel [label="Incoming cancellation",shape=folder,style=filled,fillcolor=cyan]; 72 } 73 74 subgraph { 75 rank=same; 76 check_quota [label="Is allowed by quota?",shape=ellipse,style=filled,fillcolor=gold]; 77 quota [label="Quota for resource",shape=folder]; 78 quota_for_vole [label="...applying to\nvincent.vole@example.com",shape=folder]; 79 } 80 81 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 82 83 subgraph { 84 rank=same; 85 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 86 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 87 } 88 89 add_to_quota [label="Add to quota",shape=ellipse,style=filled,fillcolor=darkorange]; 90 remove_from_quota [label="Remove from quota",shape=ellipse,style=filled,fillcolor=darkorange]; 91 92 mail -> check_quota -> schedule -> accept; 93 check_quota -> decline [style=dashed]; 94 schedule -> add_to_quota -> quota; 95 quota -> quota_for_vole -> check_quota; 96 97 cancel -> remove_from_quota -> quota; 98 } 99 }}} 100 101 }}}} 102 103 See the [[#Quota_Controls|quota controls]] documentation for more information 104 about applying quotas to resources. 105 106 == Scheduling Functions == 107 108 The [[../Preferences#scheduling_function|scheduling_function]] setting 109 indicates the behaviour of a resource when a valid request to schedule an 110 event has been received. By default, a value equivalent to the following is 111 employed: 112 113 {{{{#!table 114 '''Scheduling Functions''' || '''Decision Process''' 115 == 116 <style="vertical-align: top;"> 117 118 {{{ 119 schedule_in_freebusy 120 }}} 121 122 || 123 124 {{{#!graphviz 125 //format=svg 126 //transform=notugly 127 digraph scheduling_decisions { 128 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 129 edge [tooltip="Scheduling decisions"]; 130 131 mail [label="Incoming mail",shape=folder,style=filled,fillcolor=cyan]; 132 133 subgraph { 134 rank=same; 135 schedule_in_freebusy [label="Can schedule in free/busy?",shape=ellipse,style=filled,fillcolor=gold]; 136 freebusy [label="Free/busy",shape=folder]; 137 } 138 139 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 140 141 subgraph { 142 rank=same; 143 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 144 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 145 } 146 147 mail -> schedule_in_freebusy -> schedule -> accept; 148 schedule_in_freebusy -> decline [style=dashed]; 149 freebusy -> schedule_in_freebusy; 150 } 151 }}} 152 153 }}}} 154 155 As described above, this merely attempts to schedule an event in the free 156 periods of the resource's schedule. However, no attempt is made to reject the 157 booking of the resource according to the identity of the organiser. 158 159 === Identity Controls === 160 161 Although identity controls may be implemented in the e-mail system, 162 effectively preventing the messages from addresses other than those within 163 an organisation (for example) from being delivered to the resource, it is 164 possible to use scheduling functions to implement such controls instead. 165 166 ==== Same Domain Membership ==== 167 168 For instance, the following combines the default free/busy check with a 169 test that the organiser belongs to the same Internet mail domain (by using 170 the organiser's address): 171 172 {{{{#!table 173 '''Scheduling Functions''' || '''Decision Process''' 174 == 175 <style="vertical-align: top;"> 176 177 {{{ 178 schedule_in_freebusy 179 same_domain_only 180 }}} 181 182 || 183 184 {{{#!graphviz 185 //format=svg 186 //transform=notugly 187 digraph scheduling_decisions { 188 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 189 edge [tooltip="Scheduling decisions"]; 190 191 mail [label="Incoming mail",shape=folder,style=filled,fillcolor=cyan]; 192 193 subgraph { 194 rank=same; 195 schedule_in_freebusy [label="Can schedule in free/busy?",shape=ellipse,style=filled,fillcolor=gold]; 196 freebusy [label="Free/busy",shape=folder]; 197 } 198 199 same_domain_only [label="Organiser has resource domain?",shape=ellipse,style=filled,fillcolor=gold]; 200 201 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 202 203 subgraph { 204 rank=same; 205 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 206 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 207 } 208 209 mail -> schedule_in_freebusy -> same_domain_only -> schedule -> accept; 210 schedule_in_freebusy -> decline [style=dashed]; 211 same_domain_only -> decline [style=dashed]; 212 freebusy -> schedule_in_freebusy; 213 } 214 }}} 215 216 }}}} 217 218 Note that if the first function is omitted, no check against the resource's 219 schedule will occur, so it is necessary to mention any such function in the 220 list. 221 222 ==== Access Control Lists ==== 223 224 A simple domain-related test may not be sufficient to control access to a 225 resource. Thus, another function is provided to exercise a finer degree of 226 control over event participants. For example: 227 228 {{{{#!table 229 '''Scheduling Functions and Data''' || '''Decision Process''' 230 == 231 <style="vertical-align: top;"> 232 233 {{{ 234 schedule_in_freebusy 235 access_control_list 236 }}} 237 238 Access control list: 239 240 {{{ 241 accept 242 }}} 243 244 || 245 246 {{{#!graphviz 247 //format=svg 248 //transform=notugly 249 digraph scheduling_decisions { 250 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 251 edge [tooltip="Scheduling decisions"]; 252 253 mail [label="Incoming mail",shape=folder,style=filled,fillcolor=cyan]; 254 255 subgraph { 256 rank=same; 257 schedule_in_freebusy [label="Can schedule in free/busy?",shape=ellipse,style=filled,fillcolor=gold]; 258 freebusy [label="Free/busy",shape=folder]; 259 } 260 261 subgraph { 262 rank=same; 263 access_control_list [label="Access control list permits booking?",shape=ellipse,style=filled,fillcolor=gold]; 264 acl [label="acl setting",shape=folder]; 265 } 266 267 accept_default [label="Accept invitation by default",shape=ellipse,style=filled,fillcolor=darkorange]; 268 end_acl [label="end",shape=ellipse,style=filled,fillcolor=darkorange]; 269 270 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 271 272 subgraph { 273 rank=same; 274 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 275 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 276 } 277 278 mail -> schedule_in_freebusy -> access_control_list -> accept_default -> end_acl -> schedule -> accept; 279 end_acl -> decline [style=dashed]; 280 schedule_in_freebusy -> decline [style=dashed]; 281 freebusy -> schedule_in_freebusy; 282 acl -> access_control_list; 283 } 284 }}} 285 286 }}}} 287 288 To accompany the scheduling functions, the [[../Preferences#acl|acl]] setting 289 in the resource's preferences must be set, or if a separate file is more 290 appropriate, its full path may be given as an argument to `access_control_list`: 291 292 {{{ 293 schedule_in_freebusy 294 access_control_list /etc/imip-agent/resources.acl 295 }}} 296 297 Within the file provided by the setting or separate file, a list of rules 298 must describe the handling procedure for an event. For example, the following 299 was given in the above example: 300 301 {{{ 302 accept 303 }}} 304 305 This will merely accept all invitations, anyway. However, it may be 306 appropriate to prevent certain users from using resources. For example: 307 308 {{{{#!table 309 '''Scheduling Functions and Data''' || '''Decision Process''' 310 == 311 <style="vertical-align: top;"> 312 313 {{{ 314 schedule_in_freebusy 315 access_control_list 316 }}} 317 318 Access control list: 319 320 {{{ 321 accept 322 decline attendee simon.skunk@example.com 323 }}} 324 325 || 326 327 {{{#!graphviz 328 //format=svg 329 //transform=notugly 330 digraph scheduling_decisions { 331 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 332 edge [tooltip="Scheduling decisions"]; 333 334 mail [label="Incoming mail",shape=folder,style=filled,fillcolor=cyan]; 335 336 subgraph { 337 rank=same; 338 schedule_in_freebusy [label="Can schedule in free/busy?",shape=ellipse,style=filled,fillcolor=gold]; 339 freebusy [label="Free/busy",shape=folder]; 340 } 341 342 subgraph { 343 rank=same; 344 access_control_list [label="Access control list permits booking?",shape=ellipse,style=filled,fillcolor=gold]; 345 acl [label="acl setting",shape=folder]; 346 } 347 348 accept_default [label="Accept invitation by default",shape=ellipse,style=filled,fillcolor=darkorange]; 349 decline_attendee [label="Is attendee simon.skunk@example.com?",shape=ellipse,style=filled,fillcolor=darkorange]; 350 end_acl [label="end",shape=ellipse,style=filled,fillcolor=darkorange]; 351 352 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 353 354 subgraph { 355 rank=same; 356 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 357 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 358 } 359 360 mail -> schedule_in_freebusy -> access_control_list -> accept_default -> decline_attendee -> end_acl -> schedule -> accept; 361 end_acl -> decline [style=dashed]; 362 schedule_in_freebusy -> decline [style=dashed]; 363 freebusy -> schedule_in_freebusy; 364 acl -> access_control_list; 365 } 366 }}} 367 368 }}}} 369 370 This example indicates that by default, invitations will be accepted, but if 371 one of the attendees of an event is `simon.skunk@example.com`, the invitation 372 will be declined. However, it may be the case that this rule should be 373 overridden under certain circumstances. For example: 374 375 {{{{#!table 376 '''Scheduling Functions and Data''' || '''Decision Process''' 377 == 378 <style="vertical-align: top;"> 379 380 {{{ 381 schedule_in_freebusy 382 access_control_list 383 }}} 384 385 Access control list: 386 387 {{{ 388 accept 389 decline attendee simon.skunk@example.com 390 accept organiser paul.boddie@example.com 391 }}} 392 393 || 394 395 {{{#!graphviz 396 //format=svg 397 //transform=notugly 398 digraph scheduling_decisions { 399 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 400 edge [tooltip="Scheduling decisions"]; 401 402 mail [label="Incoming mail",shape=folder,style=filled,fillcolor=cyan]; 403 404 subgraph { 405 rank=same; 406 schedule_in_freebusy [label="Can schedule in free/busy?",shape=ellipse,style=filled,fillcolor=gold]; 407 freebusy [label="Free/busy",shape=folder]; 408 } 409 410 subgraph { 411 rank=same; 412 access_control_list [label="Access control list permits booking?",shape=ellipse,style=filled,fillcolor=gold]; 413 acl [label="acl setting",shape=folder]; 414 } 415 416 accept_default [label="Accept invitation by default",shape=ellipse,style=filled,fillcolor=darkorange]; 417 decline_attendee [label="Is attendee simon.skunk@example.com?",shape=ellipse,style=filled,fillcolor=darkorange]; 418 accept_organiser [label="Is organiser paul.boddie@example.com?",shape=ellipse,style=filled,fillcolor=darkorange]; 419 end_acl [label="end",shape=ellipse,style=filled,fillcolor=darkorange]; 420 421 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 422 423 subgraph { 424 rank=same; 425 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 426 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 427 } 428 429 mail -> schedule_in_freebusy -> access_control_list -> accept_default -> decline_attendee -> accept_organiser -> end_acl -> schedule -> accept; 430 end_acl -> decline [style=dashed]; 431 schedule_in_freebusy -> decline [style=dashed]; 432 freebusy -> schedule_in_freebusy; 433 acl -> access_control_list; 434 } 435 }}} 436 437 }}}} 438 439 Here, the stated organiser may still arrange a booking of the resource where 440 the previously-mentioned attendee is involved. 441 442 === Quota Controls === 443 444 The [[#Confirmation_and_Retraction_Functions|confirmation and retraction functions]] 445 section provides an example of applying quotas to event participants. However, 446 this section describes the operation of the quota system in more detail. 447 448 In contrast to each user's stored information which consolidates information 449 related to that user's own schedule, the quota system consolidates information 450 related to the schedules of one or more resources, thus enabling observations 451 to be made about their collective usage. 452 453 First, consider a resource such as a car where an organiser of an event may be 454 booking the car for travel purposes. A quota prevents the organiser from 455 booking the resource too much and denying other users access to it. 456 457 Now consider a number of separate car resources. An organiser might attempt to 458 get around any individual resource quota by booking a number of different cars. 459 By grouping the resources together, the organiser will exhaust a quota set on 460 the group of resources as reservations are made for the different members of 461 the group. 462 463 ==== Initialising Quotas ==== 464 465 Within the journal storage area (described in the [[../FilesystemUsage|filesystem guide]]), 466 a quota group directory must be initialised with a `limits` file indicating 467 the amount of time that can be occupied by the cumulative total of all events 468 scheduled by an individual user or a group of which they are a member. For 469 example: 470 471 {{{ 472 mailto:vincent.vole@example.com PT10H 473 }}} 474 475 This indicates that the given user may only reserve 10 hours of events or less. 476 Attempts to schedule more time will be declined. 477 478 To impose a general quota, the special `*` identity can be used: 479 480 {{{ 481 * PT10H 482 }}} 483 484 When a user identity is not listed and no general quota is defined, that 485 particular user will be unable to reserve the resource unless defined as a 486 member of a group listed in the `limits` file, as described below. 487 488 ==== Sharing Quotas Across Users ==== 489 490 When the use of resources is to be shared between users in such a way that 491 groups of users will be sharing a single quota, the `groups` file in the 492 quota directory must be defined, mapping each user identity to the group to 493 which they will belong. For example: 494 495 {{{ 496 mailto:vincent.vole@example.com developers 497 mailto:harvey.horse@example.com developers 498 mailto:paul.boddie@example.com developers 499 mailto:simon.skunk@example.com testers 500 }}} 501 502 The group identity can then be employed in the `limits` file: 503 504 {{{ 505 developers PT10H 506 testers PT20H 507 }}} 508 509 Limits apply to individuals, then to groups, then the general quota applies. 510 Thus, when a group is not listed, the general quota applies; without a general 511 quota (and without matching individually), a group member will be unable to 512 reserve the resource. 513 514 ==== Individual Resource Quotas ==== 515 516 The trivial case of applying quotas is to give a resource its own quota. This 517 is achieved by not specifying any arguments to the `check_quota` scheduling 518 function or to the `add_to_quota` and `remove_from_quota` functions. See the 519 [[#Confirmation_and_Retraction_Functions|confirmation and retraction functions]] 520 section for an example of this. 521 522 ==== Common Resource Quotas ==== 523 524 By indicating an argument to the different functions, a common quota can be 525 employed. In the following example, both resources would employ the given 526 function invocations to pool their knowledge about their schedules. 527 528 {{{{#!table 529 '''All Functions''' || '''Decision Process''' 530 == 531 <style="vertical-align: top;"> 532 533 Scheduling functions: 534 535 {{{ 536 check_quota cars 537 }}} 538 539 Confirmation functions: 540 541 {{{ 542 add_to_quota cars 543 }}} 544 545 Retraction functions: 546 547 {{{ 548 remove_from_quota cars 549 }}} 550 551 || 552 553 {{{#!graphviz 554 //format=svg 555 //transform=notugly 556 digraph scheduling_decisions { 557 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 558 edge [tooltip="Scheduling decisions"]; 559 560 subgraph { 561 rank=same; 562 mail_cadillac [label="Incoming mail\nfrom vincent.vole@example.com\nto resource-car-cadillac@example.com",shape=folder,style=filled,fillcolor=cyan]; 563 mail_pontiac [label="Incoming mail\nfrom vincent.vole@example.com\nto resource-car-pontiac@example.com",shape=folder,style=filled,fillcolor=cyan]; 564 cancel [label="Incoming cancellation",shape=folder,style=filled,fillcolor=cyan]; 565 } 566 567 subgraph { 568 rank=same; 569 check_quota [label="Is allowed by quota?",shape=ellipse,style=filled,fillcolor=gold]; 570 quota_cars [label="Quota for cars",shape=folder]; 571 quota_cars_vole [label="...applying to\nvincent.vole@example.com",shape=folder]; 572 } 573 574 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 575 576 subgraph { 577 rank=same; 578 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 579 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 580 } 581 582 add_to_quota [label="Add to quota",shape=ellipse,style=filled,fillcolor=darkorange]; 583 remove_from_quota [label="Remove from quota",shape=ellipse,style=filled,fillcolor=darkorange]; 584 585 mail_cadillac -> check_quota; 586 mail_pontiac -> check_quota -> schedule -> accept; 587 check_quota -> decline [style=dashed]; 588 schedule -> add_to_quota -> quota_cars; 589 quota_cars -> quota_cars_vole -> check_quota; 590 591 cancel -> remove_from_quota -> quota_cars; 592 } 593 }}} 594 595 }}}} 596 597 ==== Collective Scheduling ==== 598 599 Consider two separate resources: both may be reserved at the same time by the 600 same organiser; neither resource would normally decline the reservation on the 601 basis of schedule availability, should the period concerned be free. However, 602 it may be undesirable for one organiser to occupy both resources at the same 603 time. 604 605 Consequently, a mechanism is required to pool the resource schedules in such a 606 way that any reservation performed for one resource at a given point in time 607 prohibits another reservation performed for a related resource at the same 608 point in time by the same user. 609 610 The free/busy records held for a given quota group permit such collective 611 scheduling decisions and are employed as follows: 612 613 {{{{#!table 614 '''All Functions''' || '''Decision Process''' 615 == 616 <style="vertical-align: top;"> 617 618 Scheduling functions: 619 620 {{{ 621 schedule_within_quota cars 622 }}} 623 624 Confirmation functions: 625 626 {{{ 627 add_to_quota_freebusy cars 628 }}} 629 630 Retraction functions: 631 632 {{{ 633 remove_from_quota_freebusy cars 634 }}} 635 636 || 637 638 {{{#!graphviz 639 //format=svg 640 //transform=notugly 641 digraph scheduling_decisions { 642 node [shape=box,fontsize="13.0",fontname="Helvetica",tooltip="Scheduling decisions"]; 643 edge [tooltip="Scheduling decisions"]; 644 645 subgraph { 646 rank=same; 647 mail_cadillac [label="Incoming mail\nfrom vincent.vole@example.com\nto resource-car-cadillac@example.com",shape=folder,style=filled,fillcolor=cyan]; 648 mail_pontiac [label="Incoming mail\nfrom vincent.vole@example.com\nto resource-car-pontiac@example.com",shape=folder,style=filled,fillcolor=cyan]; 649 cancel [label="Incoming cancellation",shape=folder,style=filled,fillcolor=cyan]; 650 } 651 652 subgraph { 653 rank=same; 654 schedule_across_quota [label="Can be scheduled within the quota?",shape=ellipse,style=filled,fillcolor=gold]; 655 quota_cars [label="Quota for cars",shape=folder]; 656 freebusy_cars_vole [label="...recording schedule for\nvincent.vole@example.com",shape=folder]; 657 } 658 659 schedule [label="Schedule event for resource",shape=ellipse,style=filled,fillcolor=gold]; 660 661 subgraph { 662 rank=same; 663 accept [label="Accept",shape=folder,style=filled,fillcolor=cyan]; 664 decline [label="Decline",shape=folder,style=filled,fillcolor=cyan]; 665 } 666 667 add_to_quota_freebusy [label="Add to quota free/busy",shape=ellipse,style=filled,fillcolor=darkorange]; 668 remove_from_quota_freebusy [label="Remove from quota free/busy",shape=ellipse,style=filled,fillcolor=darkorange]; 669 670 mail_cadillac -> schedule_across_quota; 671 mail_pontiac -> schedule_across_quota -> schedule -> accept; 672 schedule_across_quota -> decline [style=dashed]; 673 schedule -> add_to_quota_freebusy -> quota_cars -> freebusy_cars_vole; 674 freebusy_cars_vole -> schedule_across_quota; 675 676 cancel -> remove_from_quota_freebusy -> freebusy_cars_vole; 677 } 678 }}} 679 680 }}}}