1+ /**
2+ * API Synthetic check based on https://docs.newrelic.com/docs/synthetics/synthetic-monitoring/scripting-monitors/write-synthetic-api-tests/
3+ * Flow:
4+ * 1. Get latest release tag from Github for infra-agent and integrations.
5+ * 2. Validate the right package is published in download server.
6+ *
7+ * How to install:
8+ * 1. Go to Synthetics > Create monitor in NR1.
9+ * 2. Select Scripted API check.
10+ * 3. Define appropiate settings and copy/paste this script as last step.
11+ * 4. Optionally, create an Alert Condition to get notifications.
12+ *
13+ * List of OHIs to consider in a separate synthetic check and alert
14+ * 'nri-mysql', 'nri-apache', 'nri-cassandra', 'nri-consul', 'nri-couchbase',
15+ * 'nri-elasticsearch', 'nri-f5', 'nri-haproxy', 'nri-kafka', 'nri-memcached',
16+ * 'nri-mongodb', 'nri-mssql', 'nri-mysql', 'nri-nagios', 'nri-nginx', 'nri-oracledb',
17+ * 'nri-postgresql', 'nri-rabbitmq', 'nri-redis'];
18+ */
19+ var assert = require ( 'assert' ) ;
20+ var downloadServerBaseURI = `https://download.newrelic.com/infrastructure_agent` ;
21+ var githubOrg = `https://api.github.com/repos/newrelic` ;
22+ var allRepos = [ 'infrastructure-agent' , 'nri-jmx' , 'nrjmx' , 'nri-snmp' ] ;
23+
24+ var arm64Unsupported = [ 'nri-oracledb' ] ;
25+ var windowsUnsupported = [ 'nri-oracledb' ] ;
26+ // windows packages can be .msi or .exe
27+ var windowsExes = [ 'nri-oracledb' , 'nri-kafka' , 'nri-jmx' , 'nri-cassandra' ] ;
28+
29+ function checkLatestReleases ( repos ) {
30+ repos . forEach ( repo => {
31+ var repoURL = `${ githubOrg } /${ repo } /releases/latest` ;
32+ console . log ( `Getting ${ repoURL } ` ) ;
33+ $http . get ( {
34+ 'uri' : repoURL ,
35+ 'headers' : { 'User-Agent' : 'newrelic-ohai' }
36+ } ,
37+ function ( err , response , body ) {
38+ assert . equal ( response . statusCode , 200 , `Expected 200 getting releases got ${ response . statusCode } ${ err } ` ) ;
39+
40+ // Our release tags might or not contain a 'v' prefix (1.0.0 vs v1.0.0)
41+ var latestRelease = JSON . parse ( body ) . tag_name . replace ( 'v' , '' ) ;
42+ checkPackagesInCDN ( repo , latestRelease ) ;
43+ }
44+ ) ;
45+ } ) ;
46+ }
47+
48+ function checkPackagesInCDN ( repo , latestRelease ) {
49+ // need to consider arm64 vs aarch64 vs noarch alternatives
50+ var archs = [
51+ {
52+ archInUrl : 'x86_64' ,
53+ archInPackage : repo === 'nrjmx' ? 'noarch' : 'x86_64'
54+ } ] ;
55+ if ( arm64Unsupported . indexOf ( repo ) < 0 ) {
56+ archs . push ( {
57+ archInUrl : 'aarch64' ,
58+ archInPackage : repo === 'nrjmx' ? 'noarch' : 'arm64'
59+ } ) ;
60+ }
61+
62+ // except from infra-agent, all OHIs have consistent repos and package names.
63+ var packagePrefix = repo === 'infrastructure-agent' ? 'newrelic-infra' : repo ;
64+
65+ // TODO: add DockerHub images checks
66+ checkSLES ( packagePrefix , latestRelease , archs ) ;
67+ checkAL2 ( packagePrefix , latestRelease , archs ) ;
68+ checkRHEL ( packagePrefix , latestRelease , archs ) ;
69+ checkDeb ( packagePrefix , latestRelease , archs ) ;
70+
71+ if ( windowsUnsupported . indexOf ( packagePrefix ) < 0 ) {
72+ checkWindows ( packagePrefix , latestRelease ) ;
73+ }
74+ }
75+
76+ function checkSLES ( packagePrefix , latestRelease , archs ) {
77+ for ( var i = 0 ; i < archs . length ; i ++ ) {
78+ var packageStructure = packagePrefix === 'newrelic-infra' ? `${ packagePrefix } -${ latestRelease } -1.sles12.4.${ archs [ i ] . archInPackage } .rpm` :
79+ `${ packagePrefix } -${ latestRelease } -1.${ archs [ i ] . archInPackage } .rpm` ;
80+ var downloadServerURI = `${ downloadServerBaseURI } /linux/zypp/sles/12.4/${ archs [ i ] . archInUrl } /${ packageStructure } ` ;
81+ checkFileInServer ( downloadServerURI ) ;
82+ }
83+ }
84+
85+ function checkAL2 ( packagePrefix , latestRelease , archs ) {
86+ for ( var i = 0 ; i < archs . length ; i ++ ) {
87+ var packageStructure = packagePrefix === 'newrelic-infra' ? `${ packagePrefix } -${ latestRelease } -1.amazonlinux-2.${ archs [ i ] . archInPackage } .rpm` :
88+ `${ packagePrefix } -${ latestRelease } -1.${ archs [ i ] . archInPackage } .rpm` ;
89+
90+ var downloadServerURI = `${ downloadServerBaseURI } /linux/yum/amazonlinux/2/${ archs [ i ] . archInUrl } /${ packageStructure } ` ;
91+ checkFileInServer ( downloadServerURI ) ;
92+ }
93+ }
94+
95+ function checkRHEL ( packagePrefix , latestRelease , archs ) {
96+ for ( var i = 0 ; i < archs . length ; i ++ ) {
97+ var packageStructure = packagePrefix === 'newrelic-infra' ? `${ packagePrefix } -${ latestRelease } -1.el8.${ archs [ i ] . archInPackage } .rpm` :
98+ `${ packagePrefix } -${ latestRelease } -1.${ archs [ i ] . archInPackage } .rpm` ;
99+
100+ var downloadServerURI = `${ downloadServerBaseURI } /linux/yum/el/8/${ archs [ i ] . archInUrl } /${ packageStructure } ` ;
101+ checkFileInServer ( downloadServerURI ) ;
102+ }
103+ }
104+
105+ function checkDeb ( packagePrefix , latestRelease , archs ) {
106+ for ( var i = 0 ; i < archs . length ; i ++ ) {
107+ var arch = archs [ i ] . archInPackage === 'x86_64' ? 'amd64' : archs [ i ] . archInPackage ;
108+ var packageStructure = packagePrefix === 'newrelic-infra' ? `${ packagePrefix } _systemd_${ latestRelease } _${ arch } .deb` :
109+ `${ packagePrefix } _${ latestRelease } -1_${ arch } .deb` ;
110+
111+ var downloadServerURI = `${ downloadServerBaseURI } /linux/apt/pool/main/n/${ packagePrefix } /${ packageStructure } ` ;
112+ checkFileInServer ( downloadServerURI ) ;
113+ }
114+ }
115+
116+ /**
117+ * Agent URL example:
118+ * - https://download.newrelic.com/infrastructure_agent/windows/newrelic-infra.1.20.4.msi
119+ * Integrations:
120+ * - https://download.newrelic.com/infrastructure_agent/windows/integrations/nri-mysql/nri-mysql-amd64.1.7.0.msi
121+ *
122+ * 'nri-oracledb', 'nri-kafka', 'nri-jmx', 'nri-cassandra' are installers (.exe)
123+ */
124+ function checkWindows ( packagePrefix , latestRelease ) {
125+ var downloadServerURI ;
126+ if ( packagePrefix === 'newrelic-infra' ) {
127+ downloadServerURI = `${ downloadServerBaseURI } /windows/${ packagePrefix } .${ latestRelease } .msi` ;
128+ } else if ( windowsExes . indexOf ( packagePrefix ) >= 0 ) {
129+ downloadServerURI = `${ downloadServerBaseURI } /windows/integrations/${ packagePrefix } /${ packagePrefix } -amd64-installer.${ latestRelease } .exe` ;
130+ } else {
131+ downloadServerURI = `${ downloadServerBaseURI } /windows/integrations/${ packagePrefix } /${ packagePrefix } -amd64.${ latestRelease } .msi` ;
132+ }
133+ checkFileInServer ( downloadServerURI ) ;
134+ }
135+
136+ function checkFileInServer ( downloadServerURI ) {
137+ $http . head ( {
138+ 'uri' : downloadServerURI
139+ } ,
140+ function ( err , response , body ) {
141+ assert . equal ( response . statusCode , 200 , `Expected 200, got ${ response . statusCode } in ${ downloadServerURI } ` ) ;
142+ }
143+ ) ;
144+ }
145+
146+ checkLatestReleases ( allRepos ) ;
0 commit comments