github.com/hernad/nomad@v1.6.112/ui/app/serializers/job.js (about)

     1  /**
     2   * Copyright (c) HashiCorp, Inc.
     3   * SPDX-License-Identifier: MPL-2.0
     4   */
     5  
     6  import { assign } from '@ember/polyfills';
     7  import ApplicationSerializer from './application';
     8  import queryString from 'query-string';
     9  import classic from 'ember-classic-decorator';
    10  
    11  @classic
    12  export default class JobSerializer extends ApplicationSerializer {
    13    attrs = {
    14      parameterized: 'ParameterizedJob',
    15    };
    16  
    17    separateNanos = ['SubmitTime'];
    18  
    19    normalize(typeHash, hash) {
    20      hash.NamespaceID = hash.Namespace;
    21  
    22      // ID is a composite of both the job ID and the namespace the job is in
    23      hash.PlainId = hash.ID;
    24      hash.ID = JSON.stringify([hash.ID, hash.NamespaceID || 'default']);
    25  
    26      // ParentID comes in as "" instead of null
    27      if (!hash.ParentID) {
    28        hash.ParentID = null;
    29      } else {
    30        hash.ParentID = JSON.stringify([
    31          hash.ParentID,
    32          hash.NamespaceID || 'default',
    33        ]);
    34      }
    35  
    36      // Job Summary is always at /:job-id/summary, but since it can also come from
    37      // the job list, it's better for Ember Data to be linked by ID association.
    38      hash.SummaryID = hash.ID;
    39  
    40      // Periodic is a boolean on list and an object on single
    41      if (hash.Periodic instanceof Object) {
    42        hash.PeriodicDetails = hash.Periodic;
    43        hash.Periodic = true;
    44      }
    45  
    46      // Parameterized behaves like Periodic
    47      if (hash.ParameterizedJob instanceof Object) {
    48        hash.ParameterizedDetails = hash.ParameterizedJob;
    49        hash.ParameterizedJob = true;
    50      }
    51  
    52      // If the hash contains summary information, push it into the store
    53      // as a job-summary model.
    54      if (hash.JobSummary) {
    55        this.store.pushPayload('job-summary', {
    56          'job-summary': [hash.JobSummary],
    57        });
    58      }
    59  
    60      return super.normalize(typeHash, hash);
    61    }
    62  
    63    extractRelationships(modelClass, hash) {
    64      const namespace =
    65        !hash.NamespaceID || hash.NamespaceID === 'default'
    66          ? undefined
    67          : hash.NamespaceID;
    68      const { modelName } = modelClass;
    69  
    70      const apiNamespace = this.store
    71        .adapterFor(modelClass.modelName)
    72        .get('namespace');
    73  
    74      const [jobURL] = this.store
    75        .adapterFor(modelName)
    76        .buildURL(modelName, hash.ID, hash, 'findRecord')
    77        .split('?');
    78  
    79      const variableLookup = hash.ParentID
    80        ? JSON.parse(hash.ParentID)[0]
    81        : hash.PlainId;
    82  
    83      return assign(super.extractRelationships(...arguments), {
    84        allocations: {
    85          links: {
    86            related: buildURL(`${jobURL}/allocations`, { namespace }),
    87          },
    88        },
    89        versions: {
    90          links: {
    91            related: buildURL(`${jobURL}/versions`, { namespace, diffs: true }),
    92          },
    93        },
    94        deployments: {
    95          links: {
    96            related: buildURL(`${jobURL}/deployments`, { namespace }),
    97          },
    98        },
    99        latestDeployment: {
   100          links: {
   101            related: buildURL(`${jobURL}/deployment`, { namespace }),
   102          },
   103        },
   104        evaluations: {
   105          links: {
   106            related: buildURL(`${jobURL}/evaluations`, { namespace }),
   107          },
   108        },
   109        services: {
   110          links: {
   111            related: buildURL(`${jobURL}/services`, { namespace }),
   112          },
   113        },
   114        variables: {
   115          links: {
   116            related: buildURL(`/${apiNamespace}/vars`, {
   117              prefix: `nomad/jobs/${variableLookup}`,
   118              namespace,
   119            }),
   120          },
   121        },
   122        scaleState: {
   123          links: {
   124            related: buildURL(`${jobURL}/scale`, { namespace }),
   125          },
   126        },
   127        recommendationSummaries: {
   128          links: {
   129            related: buildURL(`/${apiNamespace}/recommendations`, {
   130              job: hash.PlainId,
   131              namespace: hash.NamespaceID || 'default',
   132            }),
   133          },
   134        },
   135      });
   136    }
   137  }
   138  
   139  function buildURL(path, queryParams) {
   140    const qpString = queryString.stringify(queryParams);
   141    if (qpString) {
   142      return `${path}?${qpString}`;
   143    }
   144    return path;
   145  }