[comment]: # ({96feb912-d3accdff})
# 1 Objectes JavaScript addicionals

[comment]: # ({/96feb912-d3accdff})

[comment]: # ({dfa8c394-ab8bd378})
### Vista general

Aquesta secció descriu les addicions de Zabbix al llenguatge JavaScript implementats amb Duktape i les funcions globals de JavaScript admeses.

[comment]: # ({/dfa8c394-ab8bd378})

[comment]: # ({c73f2449-c73f2449})
### Objectes integrats

[comment]: # ({/c73f2449-c73f2449})

[comment]: # ({500e2fca-e5dc8dd0})
#### Zabbix

L'objecte Zabbix proporciona interacció amb la funcionalitat interna de Zabbix.

|Mètode|Descripció|
|--|---------|
|`log(loglevel, message)`|Escriu <missatge> al registre de Zabbix emprant el nivell de registre <loglevel> (veieu la configuració de DebugLevel al fitxer de configuració).|

Exemple:

     Zabbix.log(3, "aquesta és una entrada de registre escrita amb el nivell de registre 'Avís'")

Podeu emprar els àlies següents:

|Àlies|Àlies a |
|-----|--------|
|console.log(objecte)|Zabbix.log(4, JSON.stringify(objecte))|
|console.warn(objecte)|Zabbix.log(3, JSON.stringify(objecte))|
|console.error(objecte)|Zabbix.log(2, JSON.stringify(objecte))|

::: noteimportant
La mida total de tots els missatges registrats és limitada a 8 Mo per execució de l'script.
:::

|Mètode|Descripció|
|--|---------|
|`sleep(delay)`|Endarrereix l'execució de JavaScript `delay` mil·lisegons. |

Exemple (execució endarrerida durant 15 segons):

     Zabbix.sleep(15000)

[comment]: # ({/500e2fca-e5dc8dd0})

[comment]: # ({49b8bf62-51c5ca42})
#### HttpRequest

::: noteimportant
"HttpRequest" és un nom nou per a aquest objecte des de Zabbix 5.4.
Abans s'anomenava "CurlHttpRequest".
Els noms dels mètodes també es van canviar a Zabbix 5.4.
Els noms antics d'objectes/mètodes ara són obsolets i el seu suport es discontinuarà després de Zabbix 6.0.
:::

Aquest objecte encapsula el controlador cURL que permet fer peticions HTTP senzilles.
Els errors es llancen com a excepcions.

::: noteimportant
La inicialització de diversos objectes `HttpRequest` és limitada a 10 per execució de l'script.
:::

|Mètode|Descripció|
|--|---------|
|`addHeader(name, value)`|Afegiu un camp de capçalera HTTP. Aquest camp s'empra per a totes les peticions posteriors fins que s'esborra amb el mètode clearHeader().<br>L'allargada total dels camps de capçalera que es poden afegir a un únic objecte `HttpRequest` és limitada a 128Ko (inclosos caràcters especials i noms de capçalera).|
|`clearHeader()`|Esborra la capçalera HTTP. Si no s'estableix cap camp de capçalera, `HttpRequest` establirà el Content-Type a application/json si les dades publicades són en format JSON; text/llaç en cas contrari.|
|`connect(url)`|Envieu la petició HTTP CONNECT a l'URL i retorneu la resposta.|
|`customRequest(method, url, data)`|Permet especificar qualsevol mètode HTTP al primer paràmetre. Envieu la petició de mètode a l'URL amb la càrrega útil de *dades* opcional i la resposta de retorn.|
|`delete(url, data)`|Envia la petició HTTP DELETE a l'URL amb la càrrega útil opcional *data* i retorna la resposta.|
|`getHeaders(<asArray>)`|Retorna l'objecte dels camps de capçalera HTTP rebuts.<br>El paràmetre `asArray` es pot establir com a "true" (per exemple, `getHeaders(true)`), "false" o ésser indefinit. Si es defineix com a "true", els valors dels camps de capçalera HTTP rebuts es retornaran com a matrius; això s'ha d'emprar per recuperar els valors dels camps de diverses capçaleres amb el mateix nom.<br>Si no s'estableix o s'estableix com a "fals", els valors dels camps de capçalera HTTP rebuts es retornaran com a cadenes.
|`get(url, data)`|Envia una petició HTTP GET a l'URL amb la càrrega útil opcional *data* i retorna la resposta.|
|`head(url)`|Envia la petició HTTP HEAD a l'URL i retorna la resposta.|
|`options(url)`|Envia la petició HTTP OPTIONS a l'URL i retorna la resposta.|
|`patch(url, data)`|Envia la petició HTTP PATCH a l'URL amb la càrrega útil opcional *data* i retorna la resposta.|
|`put(url, data)`|Envia una petició HTTP PUT a l'URL amb la càrrega útil opcional *data* i retorna la resposta.|
|`post(url, data)`|Envia una petició HTTP POST a l'URL amb la càrrega útil opcional *data* i retorna la resposta.|
|`getStatus()`|Retorna el codi d'estat de la darrera petició HTTP.|
|`setProxy(proxy)`|Configura el proxy HTTP amb el valor "proxy". Si aquest paràmetre és buit, no s'empra cap proxy.|
|`setHttpAuth(bitmask, username, password)`|Defineix els mètodes d'autenticació HTTP activats (HTTPAUTH\_BASIC, HTTPAUTH\_DIGEST, HTTPAUTH\_NEGOTIATE, HTTPAUTH\_NTLM, HTTPAUTH\_NONE) al paràmetre "bitmask".<br>El HTTPAUTH\_NONE s'empra per desactivar l'autenticació HTTP.<br> Exemples:<br>`request.setHttpAuth(HTTPAUTH_NTLM\| HTTPAUTH_BASIC, nom d'usuari, mot de pas)`<br>`request.setHttpAuth(HTTPAUTH_NONE)``|
|`trace(url, data)`|Envia la petició de TRACE HTTP a l'URL amb la càrrega útil de *data* opcional i retorna la resposta.|

Exemple:

```javascript
try {
    Zabbix.log(4, 'jira webhook script value='+value);
  
    var result = {
        'tags': {
            'endpoint': 'jira'
        }
    },
    params = JSON.parse(value),
    req = new HttpRequest(),
    fields = {},
    resp;
  
    req.addHeader('Content-Type: application/json');
    req.addHeader('Authorization: Basic '+params.authentication);
  
    fields.summary = params.summary;
    fields.description = params.description;
    fields.project = {"key": params.project_key};
    fields.issuetype = {"id": params.issue_id};
    resp = req.post('https://jira.example.com/rest/api/2/issue/',
        JSON.stringify({"fields": fields})
    );
  
    if (req.getStatus() != 201) {
        throw 'Response code: '+req.getStatus();
    }
  
    resp = JSON.parse(resp);
    result.tags.issue_id = resp.id;
    result.tags.issue_key = resp.key;
} catch (error) {
    Zabbix.log(4, 'jira issue creation failed json : '+JSON.stringify({"fields": fields}));
    Zabbix.log(4, 'jira issue creation failed : '+error);
  
    result = {};
}
  
return JSON.stringify(result);
```

[comment]: # ({/49b8bf62-51c5ca42})

[comment]: # ({73df7bc5-06cac1ca})
#### XML

L'objecte XML permet el processament de dades XML en preprocessament de descoberta d'elements de baix nivell i webhooks.

::: noteimportant
  Per emprar l'objecte XML, el servidor/proxy s'ha de compilar amb suport libxml2.
:::

|Mètode|Descripció|
|--|---------|
|`XML.query(data, expression)`|Recuperar el contingut del node mitjançant XPath. Retorna null si no es troba el node.<br>**expressió** - una expressió XPath;<br>**dades** - dades XML com a cadena.|
|`XML.toJson(data)`|Converteix les dades en format XML a JSON.|
|`XML.fromJson(object)`|Converteix les dades en format JSON a XML.|

Exemple :

*Entrada:*

    <menu>
        <food type = "breakfast">
            <name>Chocolate</name>
            <price>$5.95</price>
            <description></description>
            <calories>650</calories>
        </food>
    </menu>

*Sortida:*

```json
{
    "menu": {
        "food": {
            "@type": "breakfast",
            "name": "Chocolate",
            "price": "$5.95",
            "description": null,
            "calories": "650"
        }
    }
}
```

[comment]: # ({/73df7bc5-06cac1ca})

[comment]: # ({9e03c929-a12fbdc2})
##### Regles de serialització

La conversió de XML a JSON es processarà d'acord amb les regles següents (per a les conversions de JSON a XML, s'apliquen regles inverses):

1\. Els atributs XML es convertiran en claus els noms de les quals aniran precedits per '@'.

Exemple:

*Entrada:*

     <xml foo="FOO">
       <bar>
         <baz>BAZ</baz>
       </bar>
     </xml>

*Sortida:*

```json
 {
   "xml": {
     "@foo": "FOO",
     "bar": {
       "baz": "BAZ"
     }
   }
 }
```

2\. Els elements de tancament automàtic (\<foo/\>) es convertiran com a valor "nul".

Exemple:

*Entrada:*

    <xml>
      <foo/>
    </xml>

*Sortida:*

```json
{
  "xml": {
    "foo": null
  }
}
```

3\. Els atributs buits (amb el valor "") es convertiran com a valor de cadena buida ('').

Exemple:

*Entrada:*

    <xml>
      <foo bar="" />
    </xml>

*Sortida:*

```json
{
  "xml": {
    "foo": {
      "@bar": ""
    }
  }
}
```

4\. Diversos nodes secundaris amb el mateix nom d'element es convertiran en una única clau que tingui una matriu de valors com a valor.

Exemple:

*Entrada:*

    <xml>
      <foo>BAR</foo>
      <foo>BAZ</foo>
      <foo>QUX</foo>
    </xml>

*Sortida:*

```json
{
  "xml": {
    "foo": ["BAR", "BAZ", "QUX"]
  }
}
```

5\. Si un element de text no té ni atribut ni elements fills, es convertirà a cadena.

Exemple:

*Entrada:*

    <xml>
        <foo>BAZ</foo>
    </xml>

*Sortida:*

```json
{
  "xml": {
    "foo": "BAZ"
   }
}
```

6\. Si un element de text no té fills, però té atributs: el contingut del text es convertirà a un element amb la clau '\#text' i el contingut com a valor; els atributs es convertiran tal com es descriu a la regla de serialització 1.

Exemple:

*Entrada:*

    <xml>
      <foo bar="BAR">
        BAZ
      </foo>
    </xml>

*Sortida:*

```json
{
  "xml": {
    "foo": {
      "@bar": "BAR",
      "#text": "BAZ"
    }
  }
}
```

[comment]: # ({/9e03c929-a12fbdc2})

[comment]: # ({abe08257-1368a2b0})
### Funcions globals de JavaScript

S'han afegit funcions JavaScript globals addicionals amb Duktape:

- `btoa (data)` - codifica la cadena a cadena en base64;
- `atob(base64\_string)` - des de la versió 6.0.31, descodifica la cadena en base64 com a buffer Uint8Array (a Zabbix 6.0.0 - 6.0.30 retornava una cadena descodificada).

```javascript
try {
    b64 = btoa("test string");
    buffer = atob(b64);

    // Fixeu-vos que la lògica de descodificació depen del format de les dades del buffer.
    decoded = String.fromCharCode.apply(this, [].slice.call(buffer));
} 
catch (error) {
    return {'error.name' : error.name, 'error.message' : error.message};
}
```

- `md5(dades)` - calcula el hash MD5 d'una cadena
- `sha256(dades)` - calcula el hash SHA256 d'una cadena
- `mac('\<tipus hash\>',clau,dades)` - retorna el hash HMAC com una cadena en format hexadecimal; s'admeten els `tipus hash` `MD5` i `SHA256`; els paràmetres `clau` i de `dades` admeten dades binàries.

    Exemples:
     - `hmac('md5',clau,dades)`
     - `hmac('sha256',clau,dades)`
- `sign(hash,clau,dades)` - retorna la signatura calculada (signatura RSA amb SHA-256) com a cadena, on:<br>
     **hash** - només es permet 'sha256', en cas contrari es genera un error;<br>
     **clau** - la clau privada. Ha de correspondre a l'estàndard PKCS#1 o PKCS#8. La clau es pot proporcionar de diferents formes:<br>
     - amb espais en lloc de noves línies;
     - amb o sense escapat '\n' en lloc de noves línies;
     - sense cap nova línia com una cadena d'una sola línia;
     - com a cadena en format JSON.

     La clau també es pot carregar des d'una macro d'usuari/macro/macro secreta.

     **dades** - les dades que es signaran. Pot ser una cadena (també s'admeten dades binàries) o una memòria intermèdia (Uint8Array/ArrayBuffer).<br>

    Exemple:
    - `sign('sha256',key,data)`

     OpenSSL o GnuTLS s'empren per calcular signatures. Si Zabbix s'ha compilat sense cap d'aquestes biblioteques de xifrat, es generarà un error ("Manca la biblioteca OpenSSL o GnuTLS").<br>Aquesta funció és compatible des de Zabbix 6.0.15.

[comment]: # ({/abe08257-1368a2b0})
