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