k8s.io/test-infra@v0.0.0-20240520184403-27c6b4c223d8/maintenance/oncall.html (about)

     1  <!DOCTYPE html>
     2  <!-- To "deploy": gsutil cp -Z oncall.html gs://test-infra-oncall/ -->
     3  <html lang="en">
     4  <script>
     5    var rotationsMetadata = {
     6      "google-build-admin": {
     7        "prettyName": "Google Build Admin",
     8        "slack": "@google-build-admin",
     9        "timezone": '<a href="https://time.is/PT">PT</a>',
    10        "description": 'Debian / RPM package build & publishing for releases',
    11      },
    12      "testinfra": {
    13        "prettyName": "Test Infra",
    14        "slack": "@test-infra-oncall",
    15        "timezone": '<a href="https://time.is/PT">PT</a>',
    16        "description": "Prow, TestGrid, and other Google hosted infrastructure"
    17      },
    18      "scalability": {
    19        "prettyName": "Scalability",
    20        "timezone": '<a href="https://time.is/CET">CET</a>',
    21        // TODO: description
    22      }
    23    };
    24    // extracted/modified from kubernetes/test-infra/gubernator/static/build.js
    25    function get(uri, callback) {
    26      if (uri[0] === '/') {
    27        // Matches /bucket/file/path -> [..., "bucket", "file/path"]
    28        var groups = uri.match(/([^/:]+)\/(.*)/);
    29        var bucket = groups[1], path = groups[2];
    30        var url = 'https://www.googleapis.com/storage/v1/b/' + bucket + '/o/' +
    31            encodeURIComponent(path) + '?alt=media';
    32      } else {
    33        var url = uri;
    34      }
    35      var req = new XMLHttpRequest();
    36      req.open('GET', url);
    37      req.onload = function (resp) {
    38        callback(req);
    39      };
    40      req.send();
    41    }
    42  
    43    function build_table(req) {
    44      var data = req.response;
    45      var oncall = JSON.parse(data).Oncall;
    46      var keys = Object.keys(oncall).sort();
    47  
    48      var html = '';
    49      html += '<table>';
    50      html += '<thead> <tr> <th> Rotation </th> <th> Slack </th> <th colspan=2> Current </th> <th> Time Zone </th> <th> Description </th> </tr>';
    51      html += '<tbody>';
    52      for (var i = 0; i < keys.length; i++) {
    53        var key = keys[i];
    54        var person = oncall[key];
    55        // get info about this rotation
    56        var rotationInfo = rotationsMetadata[key];
    57        var name = key;
    58        var description = "";
    59        var timezone = "";
    60        var slack = "";
    61        if (rotationInfo) {
    62          if ("prettyName" in rotationInfo) {
    63            name = rotationInfo["prettyName"];
    64          }
    65          if ("slack" in rotationInfo) {
    66            slack = rotationInfo["slack"];
    67          }
    68          if ("description" in rotationInfo) {
    69            description = rotationInfo["description"];
    70          }
    71          if ("timezone" in rotationInfo) {
    72            timezone = rotationInfo["timezone"];
    73          }
    74        }
    75        // add to table
    76        html += '<tr>';
    77        html += '<td style="font-weight: bold">' + name + '</td>';
    78        if (person) {
    79          html += '<td><code>' + slack + '</code></td>';
    80          html += '<td> <a href="https://github.com/' + person + '">' + person + ' </td>';
    81          html += '<td> <img src="https://github.com/' + person + '.png?size=125" alt=""></a> </td>';
    82          html += '<td>' + timezone + '</td>';
    83          html += '<td>' + description + '</td>';
    84        } else {
    85          html += 'None';
    86        }
    87        html += '</tr>'
    88      }
    89      html += '</tbody>';
    90      html += '</table>';
    91  
    92      // trivial XSS, but storage.googleapis.com is even more trivial XSS!
    93      document.getElementById('oncall').innerHTML = html;
    94  
    95      document.getElementById('updated').innerText = req.getResponseHeader('date');
    96    }
    97  
    98    get('/kubernetes-jenkins/oncall.json', build_table);
    99  </script>
   100  <title>K8s Oncall Rotations</title>
   101  <style>
   102    body {
   103      background-color: #eee;
   104      margin-left: auto;
   105      margin-right: auto;
   106      text-align: center;
   107    }
   108  
   109    img {
   110      padding-left: 10px;
   111      max-width: 125px;
   112    }
   113  
   114    table, th, td {
   115      border: 1px solid black;
   116    }
   117  
   118    th, td {
   119      padding: 5px;
   120      text-align: center;
   121    }
   122  
   123    #oncall {
   124      display: inline-block;
   125    }
   126  </style>
   127  <body>
   128  <h1>Kubernetes Oncall Rotations</h1>
   129  <p>Updated: <span id="updated">Never</span>
   130  <h2>NOTE: Rotations are Google-staffed, volunteer, best-effort during business-hours.</h2>
   131  <div id="oncall">Loading...</div>
   132  <div><a href="https://storage.googleapis.com/kubernetes-jenkins/oncall.json">data source</a></div>
   133  </body>
   134  </html>