Skip to content

Commit

Permalink
Iot mqtt tests (#539)
Browse files Browse the repository at this point in the history
* Adds tests for HTTP device sample

* Adds tests for MQTT sample

* A few nits from semistandard.

* Adds setting device configuration to manager.

* Fixes from http in tests / naming

* Changes RSA certs to not expire.
  • Loading branch information
gguuss committed Jan 3, 2018
1 parent 80dda29 commit 3f230da
Show file tree
Hide file tree
Showing 13 changed files with 347 additions and 107 deletions.
2 changes: 1 addition & 1 deletion iot/http_example/cloudiot_http_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function publishAsync (authToken, messageCount, numMessages) {
authToken = createJwt(argv.projectId, argv.privateKeyFile, argv.algorithm);
}

publishAsync(messageCount + 1, numMessages);
publishAsync(authToken, messageCount + 1, numMessages);
}, delayMs);
}
});
Expand Down
32 changes: 16 additions & 16 deletions iot/http_example/resources/rsa_cert.pem
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC9TCCAd2gAwIBAgIJALM44e3ivEWkMA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
BAMMBnVudXNlZDAeFw0xNzEyMDcwMDQ1MjdaFw0yNzEyMDUwMDQ1MjdaMBExDzAN
BgNVBAMMBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL4w
BxHuEyYdbiwKiD8yXY7vYpcygeOQ4/ZdEg3wCB2OuYcaFRcCuqLcTLMnuzdcL+y3
HBjWkrRW658cg3NG93Vj0iwSrga6u24CGBNYV+h8MBvwaDxk+uubnd5M/Q2OyL1J
GiMxQ1blR/71Hr5hhqaQZ2+qOF6kuf1m9rLUtMUJwOKp/PjPDmy654ZGsFWFSZmy
eRpNzmGU+KJg0o+Qf+sm75a8gQZ8AsrqveW0S/8o+zAjD0SkPcd01QBmYzQhjbi/
LGGITrzbaB3ld9umJBIcXfnYPYisJfwSsT/jFwiXhrhpxNNaIaKlTzlQIt5l8bSs
HXzJBbuIg5Jb/SyIEpkCAwEAAaNQME4wHQYDVR0OBBYEFOfaQTUVAoNb6fc7qzzl
uKyHGrCYMB8GA1UdIwQYMBaAFOfaQTUVAoNb6fc7qzzluKyHGrCYMAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBALKKDtiV1YV8k0YsNdiIXRlS3jsuoGuI
VVBrvDGz5Hel0rH9YmmfPS/Yn08kk3DF8Uynr4Xo1Zt9hmhgoq3ZoWm7MIP1+a9s
WyACyEMhVQSCzQrexRvG5ElpHx/vNjbcwiBkE5urlIvMBVt+BRRNKMNWq6F9ae63
FxRp7CtNFSbibtLJuPgCs6qoNs0nlt2FPsNvs7jpPipj69o+egVckvQjAyppirWO
+jO5hCLy7EahLz2wCn90z0Xf9lhOZni9meaV1Vy3CHHg6jwIB8/XlRaHFrOGMGXg
h8eQqsmpk9/3o8pv00yj6Hkq+swVg7Rg9FZaUiOv/HO/J7stWU7qPbI=
MIIC+DCCAeCgAwIBAgIJAMCU5DifwbH2MA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
BAMMBnVudXNlZDAeFw0xNzEyMjAxODU0MzRaFw0yMDA5MTUxODU0MzRaMBExDzAN
BgNVBAMMBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMc2
pktp/RV1g7omV5CyNi1pQugZvxn6TciLqcjHP1XYfU6mnl7ySvH1xbkzaAlL/8Y8
IqSFF4eI14qI71OT+7eLq6Ljj8j3XTqAtSANMSpi5KIRVQsa0h0rbRt7Xt1TeEd1
ErVdzdRKrKvn7wM6UID0QGxC+1gpHGo3Aaz9Q4tVxAeWM6skCDh9WHea0HNj8MPA
hS4fc83PitfITOR9eCP2HW83HXu32yFpCU96WIQGSDfHfN7vD7mDXN+iZa02GJ2K
NBiwQa3LmHmcoaru2yTB9OTf1wGRY/QETrkmA+7enq7p2RQSe6uXu97k9UgV1Wes
c4QcJ/BAsLbaWB/f2h8CAwEAAaNTMFEwHQYDVR0OBBYEFCeNUvOsKm+BB9VgO1l1
QlwS5rIEMB8GA1UdIwQYMBaAFCeNUvOsKm+BB9VgO1l1QlwS5rIEMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAG/40RXw9lojT7aTJq7f196cL1v
qYiVNeZFE2Ki0iVjzDOk1SOXRqy8v8N4ay32gD+TZOg1Yy8loscKhGCnWIRepQC8
1pyh2ZGHysICfHyxaKQgIMUzINSRI0E4bYt7kro497AodKN4P3QBH5Q6U7Ra3hG2
b1dXOBVL0kUCKOnFuByEF2Zhytyhl3bTrm/W6dvhHBGTpB2RXwnldPnyEA4rmdyk
Ui9LYmEhWeizlBpw6jcXcd9qABrUMlxBt24DB3nKo/b8h6K4gXYfgO8yYbgsB+E6
5wZGLi6nP5O98M+VmQZ5CBZSZid+sfK6eoT+Ca5vn7jSTQGzAIapc57dJEQ=
-----END CERTIFICATE-----
52 changes: 26 additions & 26 deletions iot/http_example/resources/rsa_private.pem
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+MAcR7hMmHW4s
Cog/Ml2O72KXMoHjkOP2XRIN8AgdjrmHGhUXArqi3EyzJ7s3XC/stxwY1pK0Vuuf
HINzRvd1Y9IsEq4GurtuAhgTWFfofDAb8Gg8ZPrrm53eTP0Njsi9SRojMUNW5Uf+
9R6+YYamkGdvqjhepLn9Zvay1LTFCcDiqfz4zw5suueGRrBVhUmZsnkaTc5hlPii
YNKPkH/rJu+WvIEGfALK6r3ltEv/KPswIw9EpD3HdNUAZmM0IY24vyxhiE6822gd
5XfbpiQSHF352D2IrCX8ErE/4xcIl4a4acTTWiGipU85UCLeZfG0rB18yQW7iIOS
W/0siBKZAgMBAAECggEAfwLmBdRfl2m6JNFX0hSZpJY72kuRsN8XTnUzVHmDgfHJ
9u61POvGpnLHCjIzdjIrk0NqETBjQup1aooJQ1gWdKAYQPSsobPc7geZ+nlaI9mj
61Su1/58EBKZ6Faz/HTpnHeQbAY/OW3fmeYrBOtumBgB6/HauWH7D77Oa/lfS+Ij
4f6OVAxevsi6PUtNmNtBwk5S0lZl9SFcKeHurVindquX9vWZjBEEFtNXazJttIJS
z9KX29VYwoLfflIKaUKckn8X+wYc+3u3BvH8zJpd60yQ6MSo7Sb1XkxT9549m+JW
Cb+i1K7MC/yQo4mvDtAQIVBh8p8qpd4VjpBwMuUbgQKBgQDexuAaLO3adSYFXGwW
nom6Mz/ImYcpxYo0ouAR1talbmF5/oKl9Tcwh7l1eDHfe70gfeP+g4uwAcc1hx3a
ZtXusrJFBktFezlFQnZXaE5ppryrFWeu0he0RYLAVxnL6IlP9dYQhVsTZm+7uX5d
UP7aZtmOU9ZTEsAoqvjJQXvaCQKBgQDajPebXOxIUj8ffGTeiPZczTwXux04caDC
eFKSCbAlHWgG7mR4P3fQONfEGWNHF0CxBSrew9CHmKdPyiISaExCfUaUWDDCPQCp
UE5VAHPdjSlb4lqi+cyNVlJxBJGONtyYkbQNd6N9GHMnBS8jZi7zf8VzIXpeExA4
n79Aml/YEQKBgDFrGId19AWD+z0xNWEHJjJB8CJFvHANvAzVHLOYXuEvzTvMs5qw
/N8tHHzsftO+lUPB6XOqJrCSlGhRYtPx//8FcPpS3Ru6rAerKKlXIB3buPqSsv9a
55s72DdmmvhayysLs8LSclOpY5vXGCsHLqGwMw6Zlm+zNyFOXAX5GspRAoGAaJMx
W68ABK8OM0OzhGQm9kriKTzIg5yjXspyQBzQo0HJ6B8kBgHgk8rPO68mOPsgYlPl
qogp/OgHjv9ahFJRwzLslckJM7g628loYfYAew+zrZrG4dsDjNG0Sw3zlAgeUAbQ
D+2iVhZf61josFiRuMP3t9paEi+vAFk4C3KSz/ECgYBpi1akpIzsYehW5uOL7Jhw
Hay5eshQ4vmHYuhDnn3gtT3h6J7TMwWs9pOygBG1I1b7GJ+tp4BZWJ2PmI7P8s45
jdI99WODHwv03lAzjLwigoqDUDduaYqXcGghcGht5Sknkl2uYDChwLtI5JdBZ9/x
8h9dE9oAiH/KTzhPmK1E1Q==
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDHNqZLaf0VdYO6
JleQsjYtaULoGb8Z+k3Ii6nIxz9V2H1Opp5e8krx9cW5M2gJS//GPCKkhReHiNeK
iO9Tk/u3i6ui44/I9106gLUgDTEqYuSiEVULGtIdK20be17dU3hHdRK1Xc3USqyr
5+8DOlCA9EBsQvtYKRxqNwGs/UOLVcQHljOrJAg4fVh3mtBzY/DDwIUuH3PNz4rX
yEzkfXgj9h1vNx17t9shaQlPeliEBkg3x3ze7w+5g1zfomWtNhidijQYsEGty5h5
nKGq7tskwfTk39cBkWP0BE65JgPu3p6u6dkUEnurl7ve5PVIFdVnrHOEHCfwQLC2
2lgf39ofAgMBAAECggEAa8LBI8w6jfAaiIiTF39/VQM6oQjEWg4PI2uBNU2qkgpg
hjoVMzEHn2keQrdvEJBe1GHVL3+bIcLBLXwzUdeb80aHWr6UGdbNRIc48xSPwujp
2k1b3nzsqcDC7XnH8Btl1embbCZI4Axg6UC2Bt31jDwT2TxGcAMVDtOggW4iqmyO
8v+J0j2tl+J/d7K49VtYkN5epoNn+gxpvsMbaDNmolE3Pcg2hr/h5tkzTWB53bwW
7K89FczsTvhCs8LWA/R+kKX9O9jpeUpbE6afAGdU6JCAYohClva1SIpksijV2HFg
SYZJ1QTjKfV11iBvYpj4wXGcuXgui4WL/0xCCXZt2QKBgQDq2PdYgpmJJFZHNRr9
QlgZSAsuu16t49ezAxlm4Q8orAht0Nq02l6eMHbsjV3lRmyo0vK2byMQdhaSfweB
eT7sD/TSmT7jqGEqW+jtf8mNQpAeQhJJKJ8AbERF5heKcMwk6CbFAUipc1TgCiuZ
335SyJRLUU1yUSvGqbMevUKAJQKBgQDZKAuyItjZFlyU2dVXYC8tALWjIaLwSsXw
SbCfhlMLUt7DTb8+V834ygPtEKagcaw4QwcB+brH6dO1vwL3KQWMOeZcUkXg8NCW
F71J84LLmUsZQkHx8HqLG6o/DUq+M1SuklMROAI14ZKtL0xMW/lIgICngENanUS8
m/kT+zIr8wKBgQCAkBgQDybICellf+/vdvNNm7/rbE1vekxpxieQx2IKDOtsWqpv
2R91D+j6pIUjb4MqhJi0QHD8oPjIZ9wPB/XnOvD2nUftTw8qJjiEU7FdsHO+7MKf
5CnvDFXvwf9fHVLUXXZj4MkLYoSzRT4LNWstHHr6JF72VvNVBS92g3s1NQKBgQDN
Rw3HVymmDX13OHR0JHh0Ejeh/ioI/KYgf4h3RIM8MRpjhRtD07zhchZEA3mAMfSb
OsFlHK10TZXUOLyU6DJWXGVm4F8uRHbpa4eEYK1DyaU0O24bRziQR5aoA+ij4+Ip
JCliHY/5X0NIc22swUTlRJRZwuXowsI3iTnrqYnEAQKBgQC9AhF+S6d7uIsEOg7I
Kv8ndASx7Nfsy6OQfOltgLArV4w2POQjbPYsLLrz4s82mSpS205w2OzCfcUXKLxD
mswC0Bs/U3UmJW0d1oWfUm28FjGbzGYGfOLm1dPuyNW32FbZXvO4+jaIemjtg2U7
avJDFdpNwVz/bVg0HWQWNP/C0A==
-----END PRIVATE KEY-----
2 changes: 2 additions & 0 deletions iot/http_example/system-test/cloudiot_http_example_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ test.after.always(async () => {
test(`should receive configuration message`, async (t) => {
const localDevice = `test-rsa-device`;
const localRegName = `${registryName}-rsa256`;

await tools.runAsync(`${helper} setupIotTopic ${topicName}`, cwd);
await tools.runAsync(
`${helper} createRegistry ${localRegName} ${topicName}`, cwd);
Expand All @@ -71,6 +72,7 @@ test(`should receive configuration message`, async (t) => {
test(`should send event message`, async (t) => {
const localDevice = `test-rsa-device`;
const localRegName = `${registryName}-rsa256`;

await tools.runAsync(`${helper} setupIotTopic ${topicName}`, cwd);
await tools.runAsync(
`${helper} createRegistry ${localRegName} ${topicName}`, cwd);
Expand Down
26 changes: 15 additions & 11 deletions iot/manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Run the following command to install the library dependencies for NodeJS:
listDevices <registryId> Lists the devices in a given registry.
patchEs256 <deviceId> <registryId> <es256Path> Patches a device with ES256 authorization credentials.
patchRsa256 <deviceId> <registryId> <rsa256Path> Patches a device with RSA256 authentication credentials.
setConfig <deviceId> <registryId> <configuration> <version> Sets a devices configuration to the specified data.

Options:
--projectId, -p The Project ID to use. Defaults to the value of the GCLOUD_PROJECT or GOOGLE_CLOUD_PROJECT
Expand All @@ -39,18 +40,21 @@ Run the following command to install the library dependencies for NodeJS:
--cloudRegion, -c [string] [default: "us-central1"]

Examples:
node manager.js createEs256Device my-es-device my-registry ../ec_public.pem --serviceAccount=$HOME/creds_iot.json
node manager.js createEs256Device my-es-device my-registry ../ec_public.pem
node manager.js createRegistry my-registry my-iot-topic --serviceAccount=$HOME/creds_iot.json
--api_key=abc123zz --project_id=my-project-id
node manager.js createRsa256Device my-rsa-device my-registry ../rsa_cert.pem --serviceAccount=$HOME/creds_iot.json
node manager.js createUnauthDevice my-device my-registry --serviceAccount=$HOME/creds_iot.json
node manager.js deleteDevice my-device my-registry --serviceAccount=$HOME/creds_iot.json
node manager.js deleteRegistry my-device my-registry --serviceAccount=$HOME/creds_iot.json
node manager.js getDevice my-device my-registry --serviceAccount=$HOME/creds_iot.json
node manager.js listDevices my-node-registry --serviceAccount=$HOME/creds_iot.json
node manager.js patchRsa256 my-device my-registry ../rsa_cert.pem --serviceAccount=$HOME/creds_iot.json
node manager.js patchEs256 my-device my-registry ../ec_public.pem --serviceAccount=$HOME/creds_iot.json
node manager.js setupTopic my-iot-topic --serviceAccount=$HOME/creds_iot.json
--project_id=my-project-id
node manager.js createRsa256Device my-rsa-device my-registry ../rsa_cert.pem
node manager.js createUnauthDevice my-device my-registry
node manager.js deleteDevice my-device my-registry
node manager.js deleteRegistry my-device my-registry
node manager.js getDevice my-device my-registry
node manager.js getDeviceState my-device my-registry
node manager.js getRegistry my-registry
node manager.js listDevices my-node-registry
node manager.js listRegistries
node manager.js patchRsa256 my-device my-registry ../rsa_cert.pem
node manager.js patchEs256 my-device my-registry ../ec_public.pem
node manager.js setConfig my-device my-registry "test" 0
node manager.js setupTopic my-iot-topic --serviceAccount=$HOME/creds_iot.json --projectId=my-project-id

For more information, see https://cloud.google.com/iot-core/docs
48 changes: 48 additions & 0 deletions iot/manager/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,40 @@ function getDeviceState (client, deviceId, registryId, projectId,
// [END iot_get_device_state]
}

// Retrieve the given device's state from the registry.
function setDeviceConfig (client, deviceId, registryId, projectId,
cloudRegion, data, version) {
// [START iot_set_device_config]
// Client retrieved in callback
// getClient(serviceAccountJson, function(client) {...});
// const cloudRegion = 'us-central1';
// const deviceId = 'my-device';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
// const data = 'test-data';
// const version = 0;
const parentName = `projects/${projectId}/locations/${cloudRegion}`;
const registryName = `${parentName}/registries/${registryId}`;

const binaryData = Buffer.from(data).toString('base64');
const request = {
name: `${registryName}/devices/${deviceId}`,
versionToUpdate: version,
binaryData: binaryData
};

client.projects.locations.registries.devices.modifyCloudToDeviceConfig(request,
(err, data) => {
if (err) {
console.log('Could not update config:', deviceId);
console.log('Message: ', err);
} else {
console.log('Success :', data);
}
});
// [END iot_set_device_config]
}

// Retrieve the given device from the registry.
function getRegistry (client, registryId, projectId, cloudRegion) {
// [START iot_get_registry]
Expand Down Expand Up @@ -823,6 +857,19 @@ require(`yargs`) // eslint-disable-line
getClient(opts.serviceAccount, cb);
}
)
.command(
`setConfig <deviceId> <registryId> <configuration> <version>`,
`Sets a devices configuration to the specified data.`,
{},
(opts) => {
const cb = function (client) {
setDeviceConfig(client, opts.deviceId, opts.registryId,
opts.projectId, opts.cloudRegion, opts.configuration,
opts.version || 0);
};
getClient(opts.serviceAccount, cb);
}
)
.example(`node $0 createEs256Device my-es-device my-registry ../ec_public.pem`)
.example(`node $0 createRegistry my-registry my-iot-topic --serviceAccount=$HOME/creds_iot.json --project_id=my-project-id`)
.example(`node $0 createRsa256Device my-rsa-device my-registry ../rsa_cert.pem`)
Expand All @@ -836,6 +883,7 @@ require(`yargs`) // eslint-disable-line
.example(`node $0 listRegistries`)
.example(`node $0 patchRsa256 my-device my-registry ../rsa_cert.pem`)
.example(`node $0 patchEs256 my-device my-registry ../ec_public.pem`)
.example(`node $0 setConfig my-device my-registry "test" 0`)
.example(`node $0 setupTopic my-iot-topic --serviceAccount=$HOME/creds_iot.json --projectId=my-project-id`)
.wrap(120)
.recommendCommands()
Expand Down
33 changes: 16 additions & 17 deletions iot/manager/resources/rsa_cert.pem
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIJAP2XoKtudrz5MA0GCSqGSIb3DQEBBQUAMBExDzANBgNV
BAMTBnVudXNlZDAeFw0xNzA3MTExOTE2MzBaFw0xNzA4MTAxOTE2MzBaMBExDzAN
BgNVBAMTBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANfn
stQebiazvSs0t81t7YTBNk3+Aqal0qFKY+QisbTs+BpnDcQIg6Ik974v8OtZ+t/f
c+AdCnyWpOsVzpIVpWfE6p71LsZknGgzL8/lMfgy6PFzzzU7kWzPw+MZ90VbHed3
k1fJv5E09Er684tAkyCsnr5ihol5jWq1UlnqgnHugYlJu3uOGXjdXCBtG1EzNkDx
ilfVkpgitKCGHYqXrpCCSTZ2Yhp4GrbYh0Hpxg2lF3bE5XMW8p8jl8Ykmjvq+hqt
DFOSS76FXOVG7oQU6Fc8owIRLknAK2IXPI/ciGlubivA0oQwD4E+7hLo4c2M+Jq7
faitjqPPiuemUcHrZV8CAwEAAaNyMHAwHQYDVR0OBBYEFGJSZ6h5VH/g74dez/WJ
Ftl+C3NVMEEGA1UdIwQ6MDiAFGJSZ6h5VH/g74dez/WJFtl+C3NVoRWkEzARMQ8w
DQYDVQQDEwZ1bnVzZWSCCQD9l6Crbna8+TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
DQEBBQUAA4IBAQBvygToNj8Y4hYcNwLsZwJeqhLwiSu2oQ12vpB8FnfCUsrnn9sZ
rqVheNEbr8UjPfTtgUMABxu+iabQHXT2FJqVf0J97Ted/CKUFfvXL3pMs/N5nAuV
TJzvM+Foi3NBjiDxptp3YNS+htiV/z4hX7wvFVhPf+g+Wp8RqmbZwLdcyB4ftBx1
AZ50HFv+6xH9pF6QrqS8HtfV4Jy9ZHWTnkspdP3U4sEawHxGdcjNx4zwb6oaD6hz
+F2FxlekG2gBsk4tDq+ReYqGa/G9NT4HPIIMwVyIv72ru/9HsL8yU1me3NugXWnf
IatIVphZrfrp+6yJuvmIT5vUn8tMivQp/6rI
MIIC+DCCAeCgAwIBAgIJAMCU5DifwbH2MA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
BAMMBnVudXNlZDAeFw0xNzEyMjAxODU0MzRaFw0yMDA5MTUxODU0MzRaMBExDzAN
BgNVBAMMBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMc2
pktp/RV1g7omV5CyNi1pQugZvxn6TciLqcjHP1XYfU6mnl7ySvH1xbkzaAlL/8Y8
IqSFF4eI14qI71OT+7eLq6Ljj8j3XTqAtSANMSpi5KIRVQsa0h0rbRt7Xt1TeEd1
ErVdzdRKrKvn7wM6UID0QGxC+1gpHGo3Aaz9Q4tVxAeWM6skCDh9WHea0HNj8MPA
hS4fc83PitfITOR9eCP2HW83HXu32yFpCU96WIQGSDfHfN7vD7mDXN+iZa02GJ2K
NBiwQa3LmHmcoaru2yTB9OTf1wGRY/QETrkmA+7enq7p2RQSe6uXu97k9UgV1Wes
c4QcJ/BAsLbaWB/f2h8CAwEAAaNTMFEwHQYDVR0OBBYEFCeNUvOsKm+BB9VgO1l1
QlwS5rIEMB8GA1UdIwQYMBaAFCeNUvOsKm+BB9VgO1l1QlwS5rIEMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAG/40RXw9lojT7aTJq7f196cL1v
qYiVNeZFE2Ki0iVjzDOk1SOXRqy8v8N4ay32gD+TZOg1Yy8loscKhGCnWIRepQC8
1pyh2ZGHysICfHyxaKQgIMUzINSRI0E4bYt7kro497AodKN4P3QBH5Q6U7Ra3hG2
b1dXOBVL0kUCKOnFuByEF2Zhytyhl3bTrm/W6dvhHBGTpB2RXwnldPnyEA4rmdyk
Ui9LYmEhWeizlBpw6jcXcd9qABrUMlxBt24DB3nKo/b8h6K4gXYfgO8yYbgsB+E6
5wZGLi6nP5O98M+VmQZ5CBZSZid+sfK6eoT+Ca5vn7jSTQGzAIapc57dJEQ=
-----END CERTIFICATE-----
Loading

0 comments on commit 3f230da

Please sign in to comment.