Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#175119553] Centralize environment variables in single config module #110

Merged
merged 8 commits into from
Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions CreateValidationTokenActivity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import { createTableService } from "azure-storage";
import { Millisecond } from "italia-ts-commons/lib/units";

import { VALIDATION_TOKEN_TABLE_NAME } from "io-functions-commons/dist/src/entities/validation_token";
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { ulidGenerator } from "io-functions-commons/dist/src/utils/strings";

import { getCreateValidationTokenActivityHandler } from "./handler";

import { getConfigOrThrow } from "../utils/config";

const config = getConfigOrThrow();

const TOKEN_INVALID_AFTER_MS = (1000 * 60 * 60 * 24 * 30) as Millisecond; // 30 days

// TODO: Rename this env to `StorageConnection`
// https://www.pivotaltracker.com/story/show/169591817
const storageConnectionString = getRequiredStringEnv("QueueStorageConnection");

const tableService = createTableService(storageConnectionString);
const tableService = createTableService(config.QueueStorageConnection);

const randomBytesGenerator = (size: number) =>
crypto.randomBytes(size).toString("hex");
Expand Down
10 changes: 5 additions & 5 deletions GetMessage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Context } from "@azure/functions";

import * as express from "express";

import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { secureExpressApp } from "io-functions-commons/dist/src/utils/express";
import { setAppContext } from "io-functions-commons/dist/src/utils/middlewares/context_middleware";

Expand All @@ -18,19 +17,20 @@ import createAzureFunctionHandler from "io-functions-express/dist/src/createAzur
import { cosmosdbInstance } from "../utils/cosmosdb";
import { GetMessage } from "./handler";

import { getConfigOrThrow } from "../utils/config";

// Setup Express
const app = express();
secureExpressApp(app);

const messageContainerName = getRequiredStringEnv("MESSAGE_CONTAINER_NAME");
const config = getConfigOrThrow();

const messageModel = new MessageModel(
cosmosdbInstance.container(MESSAGE_COLLECTION_NAME),
messageContainerName
config.MESSAGE_CONTAINER_NAME
);

const storageConnectionString = getRequiredStringEnv("QueueStorageConnection");
const blobService = createBlobService(storageConnectionString);
const blobService = createBlobService(config.QueueStorageConnection);

app.get(
"/api/v1/messages/:fiscalcode/:id",
Expand Down
7 changes: 4 additions & 3 deletions GetMessages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Context } from "@azure/functions";

import * as express from "express";

import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { secureExpressApp } from "io-functions-commons/dist/src/utils/express";
import { setAppContext } from "io-functions-commons/dist/src/utils/middlewares/context_middleware";

Expand All @@ -16,15 +15,17 @@ import createAzureFunctionHandler from "io-functions-express/dist/src/createAzur
import { cosmosdbInstance } from "../utils/cosmosdb";
import { GetMessages } from "./handler";

import { getConfigOrThrow } from "../utils/config";

// Setup Express
const app = express();
secureExpressApp(app);

const messageContainerName = getRequiredStringEnv("MESSAGE_CONTAINER_NAME");
const config = getConfigOrThrow();

const messageModel = new MessageModel(
cosmosdbInstance.container(MESSAGE_COLLECTION_NAME),
messageContainerName
config.MESSAGE_CONTAINER_NAME
);

app.get("/api/v1/messages/:fiscalcode", GetMessages(messageModel));
Expand Down
8 changes: 5 additions & 3 deletions GetVisibleServices/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import { createBlobService } from "azure-storage";

import * as express from "express";

import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { secureExpressApp } from "io-functions-commons/dist/src/utils/express";
import { setAppContext } from "io-functions-commons/dist/src/utils/middlewares/context_middleware";

import createAzureFunctionHandler from "io-functions-express/dist/src/createAzureFunctionsHandler";

import { GetVisibleServices } from "./handler";

import { getConfigOrThrow } from "../utils/config";

// Setup Express
const app = express();
secureExpressApp(app);

const storageConnectionString = getRequiredStringEnv("QueueStorageConnection");
const blobService = createBlobService(storageConnectionString);
const config = getConfigOrThrow();

const blobService = createBlobService(config.QueueStorageConnection);

app.get("/api/v1/services", GetVisibleServices(blobService));

Expand Down
7 changes: 0 additions & 7 deletions HandleNHNotificationCallActivity/__tests__/handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
/* tslint:disable: no-any */
// tslint:disable-next-line: no-object-mutation
process.env = {
...process.env,
AZURE_NH_ENDPOINT:
"Endpoint=sb://anendpoint.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=XXX",
AZURE_NH_HUB_NAME: "AZURE_NH_HUB_NAME"
};

import { NonEmptyString } from "italia-ts-commons/lib/strings";
import { context as contextMock } from "../../__mocks__/durable-functions";
import { PlatformEnum } from "../../generated/backend/Platform";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
/* tslint:disable:no-any */
// tslint:disable-next-line: no-object-mutation
process.env = {
...process.env,
AZURE_NH_ENDPOINT:
"Endpoint=sb://anendpoint.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=C4xIzNZv4VrUnu5jkmPH635MApRUj8wABky8VfduYqg=",
AZURE_NH_HUB_NAME: "AZURE_NH_HUB_NAME"
};
import { NonEmptyString } from "italia-ts-commons/lib/strings";
import { context as contextMock } from "../../__mocks__/durable-functions";
import { PlatformEnum } from "../../generated/backend/Platform";
Expand Down
29 changes: 14 additions & 15 deletions SendValidationEmailActivity/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { MailMultiTransportConnectionsFromString } from "io-functions-commons/dist/src/utils/multi_transport_connection";
import { MailMultiTransportConnectionsFromString } from "io-functions-commons/dist/src/utils/multi_transport_connection";
import { MultiTransport } from "io-functions-commons/dist/src/utils/nodemailer";
import { NonEmptyString } from "italia-ts-commons/lib/strings";

Expand All @@ -14,32 +13,32 @@ import {

import { initTelemetryClient } from "../utils/appinsights";

import { getConfigOrThrow } from "../utils/config";

const config = getConfigOrThrow();

// Whether we're in a production environment
const isProduction = process.env.NODE_ENV === "production";
const isProduction = config.NODE_ENV === "production";

// Optional SendGrid key
const sendgridApiKey = NonEmptyString.decode(
process.env.SENDGRID_API_KEY
).getOrElse(undefined);
const sendgridApiKey = NonEmptyString.decode(config.SENDGRID_API_KEY).getOrElse(
undefined
);

// Mailup
const mailupUsername = getRequiredStringEnv("MAILUP_USERNAME");
const mailupSecret = getRequiredStringEnv("MAILUP_SECRET");
const mailupUsername = config.MAILUP_USERNAME;
const mailupSecret = config.MAILUP_SECRET;

// Email data
const EMAIL_TITLE = "Valida l’indirizzo email che usi su IO";
const mailFrom = getRequiredStringEnv("MAIL_FROM");

// Needed to construct the email validation url
const functionsPublicUrl = getRequiredStringEnv("FUNCTIONS_PUBLIC_URL");

const HTML_TO_TEXT_OPTIONS: HtmlToTextOptions = {
ignoreImage: true, // Ignore all document images
tables: true
};

const emailDefaults = {
from: mailFrom,
from: config.MAIL_FROM,
htmlToTextOptions: HTML_TO_TEXT_OPTIONS,
title: EMAIL_TITLE
};
Expand All @@ -51,7 +50,7 @@ export type EmailDefaults = typeof emailDefaults;
// [mailup:username:password;][sendgrid:apikey:;]
// Note that multiple instances of the same provider can be provided.
const transports = MailMultiTransportConnectionsFromString.decode(
process.env.MAIL_TRANSPORTS
config.MAIL_TRANSPORTS
)
.map(getTransportsForConnections)
.getOrElse([]);
Expand All @@ -78,7 +77,7 @@ initTelemetryClient();
const activityFunctionHandler = getSendValidationEmailActivityHandler(
mailerTransporter,
emailDefaults,
functionsPublicUrl
config.FUNCTIONS_PUBLIC_URL
);

export default activityFunctionHandler;
14 changes: 9 additions & 5 deletions SendWelcomeMessagesActivity/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import { agent } from "italia-ts-commons";
import {
AbortableFetch,
Expand All @@ -8,12 +7,12 @@ import {
import { Millisecond } from "italia-ts-commons/lib/units";
import { getActivityFunction } from "./handler";

import { getConfigOrThrow } from "../utils/config";

// HTTP external requests timeout in milliseconds
const DEFAULT_REQUEST_TIMEOUT_MS = 10000;

// Needed to call notifications API
const publicApiUrl = getRequiredStringEnv("PUBLIC_API_URL");
const publicApiKey = getRequiredStringEnv("PUBLIC_API_KEY");
const config = getConfigOrThrow();

// HTTP-only fetch with optional keepalive agent
// @see https://github.com/pagopa/io-ts-commons/blob/master/src/agent.ts#L10
Expand All @@ -25,6 +24,11 @@ const timeoutFetch = toFetch(
setFetchTimeout(DEFAULT_REQUEST_TIMEOUT_MS as Millisecond, abortableFetch)
);

const index = getActivityFunction(publicApiUrl, publicApiKey, timeoutFetch);
// Needed to call notifications API
const index = getActivityFunction(
config.PUBLIC_API_URL,
config.PUBLIC_API_KEY,
timeoutFetch
);

export default index;
14 changes: 1 addition & 13 deletions StoreSpidLogs/__test__/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
/* tslint:disable:no-any */
/* tslint:disable:no-object-mutation */

process.env = {
APPINSIGHTS_INSTRUMENTATIONKEY: "foo",
QueueStorageConnection: "foobar",
SPID_BLOB_CONTAINER_NAME: "spidblob",
SPID_BLOB_STORAGE_CONNECTION_STRING: "foobar",
SPID_LOGS_PUBLIC_KEY: `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhiXpvLD8UMMUy1T2JCzo/Sj5E
l09Fs0z2U4aA37BrXlSo1DwQ2O9i2XFxXGJmE83siSWEfRlMWlabMu7Yj6dkZvmj
dGIO4gotO33TgiAQcwRo+4pwjoCN7Td47yssCcj9C727zBt+Br+XK7B1bRcqjc0J
YdF4yiVtD7G4RDXmRQIDAQAB
-----END PUBLIC KEY-----`
};

import { format } from "date-fns";
import { toPlainText } from "italia-ts-commons/lib/encrypt";
import { IPString } from "italia-ts-commons/lib/strings";
Expand Down Expand Up @@ -92,6 +79,7 @@ describe("StoreSpidLogs", () => {
}
};
const blobItem = await index(mockedContext as any, aSpidMsgItem);
console.log(blobItem);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woops

const blob = blobItem as IOutputBinding;
const encryptedSpidBlobItem = blob.spidRequestResponse;
const decryptedRequestPayload = toPlainText(
Expand Down
6 changes: 3 additions & 3 deletions StoreSpidLogs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Context } from "@azure/functions";
import { sequenceS } from "fp-ts/lib/Apply";
import { either } from "fp-ts/lib/Either";
import { curry } from "fp-ts/lib/function";
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";
import * as t from "io-ts";
import { UTCISODateFromString } from "italia-ts-commons/lib/dates";
import {
Expand All @@ -12,9 +11,10 @@ import {
import { readableReport } from "italia-ts-commons/lib/reporters";
import { IPString, PatternString } from "italia-ts-commons/lib/strings";
import { initTelemetryClient } from "../utils/appinsights";
import { getConfigOrThrow } from "../utils/config";

const rsaPublicKey = getRequiredStringEnv("SPID_LOGS_PUBLIC_KEY");
const encrypt = curry(toEncryptedPayload)(rsaPublicKey);
const config = getConfigOrThrow();
const encrypt = curry(toEncryptedPayload)(config.SPID_LOGS_PUBLIC_KEY);

/**
* Payload of the stored blob item
Expand Down
22 changes: 14 additions & 8 deletions UpdateSubscriptionsFeedActivity/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@ import { createTableService, TableUtilities } from "azure-storage";
import { readableReport } from "italia-ts-commons/lib/reporters";
import { FiscalCode } from "italia-ts-commons/lib/strings";

import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";

import { ServiceId } from "io-functions-commons/dist/generated/definitions/ServiceId";

import { isNone } from "fp-ts/lib/Option";
import { deleteTableEntity, insertTableEntity } from "../utils/storage";

const storageConnectionString = getRequiredStringEnv("QueueStorageConnection");
const tableService = createTableService(storageConnectionString);
import { getConfigOrThrow } from "../utils/config";

const config = getConfigOrThrow();

const tableService = createTableService(config.QueueStorageConnection);

const subscriptionsFeedTable = getRequiredStringEnv("SUBSCRIPTIONS_FEED_TABLE");
const insertEntity = insertTableEntity(
tableService,
config.SUBSCRIPTIONS_FEED_TABLE
);

const insertEntity = insertTableEntity(tableService, subscriptionsFeedTable);
const deleteEntity = deleteTableEntity(tableService, subscriptionsFeedTable);
const deleteEntity = deleteTableEntity(
tableService,
config.SUBSCRIPTIONS_FEED_TABLE
);

const eg = TableUtilities.entityGenerator;

Expand Down Expand Up @@ -58,7 +64,7 @@ export type Input = t.TypeOf<typeof Input>;

// When the function starts, attempt to create the table if it does not exist
// Note that we cannot log anything just yet since we don't have a Context
tableService.createTableIfNotExists(subscriptionsFeedTable, () => 0);
tableService.createTableIfNotExists(config.SUBSCRIPTIONS_FEED_TABLE, () => 0);

/**
* Updates the subscrption status of a user.
Expand Down
15 changes: 7 additions & 8 deletions docker/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ import {

import { sequenceT } from "fp-ts/lib/Apply";
import { TaskEither, taskEitherSeq, tryCatch } from "fp-ts/lib/TaskEither";
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env";

const cosmosDbKey = getRequiredStringEnv("CUSTOMCONNSTR_COSMOSDB_KEY");
const cosmosDbUri = getRequiredStringEnv("CUSTOMCONNSTR_COSMOSDB_URI");
const cosmosDbName = getRequiredStringEnv("COSMOSDB_NAME");
import { getConfigOrThrow } from "../../utils/config";

const config = getConfigOrThrow();

export const cosmosdbClient = new CosmosClient({
endpoint: cosmosDbUri,
key: cosmosDbKey
endpoint: config.CUSTOMCONNSTR_COSMOSDB_URI,
key: config.CUSTOMCONNSTR_COSMOSDB_KEY
});

function createDatabase(databaseName: string): TaskEither<Error, Database> {
Expand Down Expand Up @@ -56,7 +55,7 @@ const aService: Service = Service.decode({
organizationFiscalCode: "01234567890",
organizationName: "Organization name",
requireSecureChannels: false,
serviceId: process.env.REQ_SERVICE_ID,
serviceId: config.REQ_SERVICE_ID,
serviceName: "MyServiceName"
}).getOrElseL(() => {
throw new Error("Cannot decode service payload.");
Expand Down Expand Up @@ -88,7 +87,7 @@ const aNewProfile = NewProfile.decode({
throw new Error("Cannot decode new profile.");
});

createDatabase(cosmosDbName)
createDatabase(config.COSMOSDB_NAME)
.chain(db =>
sequenceT(taskEitherSeq)(
createCollection(db, "message-status", "messageId"),
Expand Down
24 changes: 24 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#This file is used for testing (jest),
#and must be renamed to .env (but not committed)
APPINSIGHTS_INSTRUMENTATIONKEY=foo
AZURE_NH_HUB_NAME=azhub
AZURE_NH_ENDPOINT=Endpoint=sb://host.docker.internal:30000;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=foobar
COSMOSDB_KEY=key
COSMOSDB_NAME=cosmoname
COSMOSDB_URI=uri
CUSTOMCONNSTR_COSMOSDB_KEY=key
CUSTOMCONNSTR_COSMOSDB_URI=uri
FUNCTIONS_PUBLIC_URL=url
MAILHOG_HOSTNAME=mailhog
MAIL_FROM=mail@example.it
MESSAGE_CONTAINER_NAME=msg
NODE_ENV=dev
PUBLIC_API_KEY=key
PUBLIC_API_URL=url
QueueStorageConnection=foobar
REQ_SERVICE_ID=req_id_dev
SPID_BLOB_CONTAINER_NAME=spidblob
SPID_BLOB_STORAGE_CONNECTION_STRING=foobar
SPID_LOGS_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhiXpvLD8UMMUy1T2JCzo/Sj5E\nl09Fs0z2U4aA37BrXlSo1DwQ2O9i2XFxXGJmE83siSWEfRlMWlabMu7Yj6dkZvmj\ndGIO4gotO33TgiAQcwRo+4pwjoCN7Td47yssCcj9C727zBt+Br+XK7B1bRcqjc0J\nYdF4yiVtD7G4RDXmRQIDAQAB\n-----END PUBLIC KEY-----"
SUBSCRIPTIONS_FEED_TABLE=feed
UBSCRIPTIONS_FEED_TABLE=feed
Loading