cookie
70 | Cookies.set(cookie_name, encoded, {
71 | expires: max_age,
72 | });
73 | // rewrite MSAM_CURRENT cookie
74 | Cookies.set(cookie_name_current, cookie_name, {
75 | expires: max_age,
76 | });
77 | } else {
78 | Cookies.remove(cookie_name_current);
79 | Cookies.remove(cookie_name);
80 | }
81 | };
82 |
83 | const clear_function_cache = function () {
84 | get_current.cache.clear();
85 | get_remembered.cache.clear();
86 | };
87 |
88 | // is there a connection override on the URL parameters?
89 | const current_url = new URL(window.location);
90 | let endpoint = current_url.searchParams.get("endpoint");
91 | const key = current_url.searchParams.get("key");
92 |
93 | if (endpoint && key) {
94 | // strip any trailing slashes
95 | if (endpoint.endsWith("/")) {
96 | endpoint = endpoint.substring(0, endpoint.length - 1);
97 | }
98 | console.log("Connection override with URL parameters");
99 | set_current(endpoint, key, false);
100 | }
101 |
102 | export { get_remembered, set_current, get_current };
103 |
--------------------------------------------------------------------------------
/source/html/js/app/main.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | // this module bootstraps the state machine, which starts the application running
5 | // wait for the signal from JQuery before loading and initializing
6 |
7 | $(window.document).ready(async function () {
8 | // say hello
9 | console.log("main");
10 | try {
11 | // minimal modules required to start running
12 | const statemachine = await import("./statemachine.js");
13 | await import("./ui/status_view.js");
14 | // start the outer FSM at the beginning
15 | statemachine.getToolStateMachine().start();
16 | } catch (error) {
17 | console.error(error);
18 | }
19 | });
20 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/cloudfront_medialive_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url + "/cached/cloudfront-distribution-medialive-input",
16 | api_key
17 | )
18 | .then((results) => {
19 | for (const connection of results) {
20 | const data = JSON.parse(connection.data);
21 | items.push({
22 | id: connection.arn,
23 | to: connection.to,
24 | from: connection.from,
25 | label: data.scheme,
26 | data: data,
27 | arrows: "to",
28 | color: {
29 | color: "black",
30 | },
31 | });
32 | }
33 | resolve(items);
34 | });
35 | });
36 | };
37 |
38 | export const module_name = "CloudFront Distribution to MediaLive Input";
39 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/helper.js:
--------------------------------------------------------------------------------
1 | export function checkAdditionalConnections(results, connection) {
2 | const shouldEndWith = connection.arn.endsWith("0") ? "1" : "0";
3 | return _.filter(results, function (o) {
4 | if (
5 | o.from === connection.from &&
6 | o.to === connection.to
7 | ) {
8 | if (o.arn.endsWith(shouldEndWith)) return true;
9 | }
10 | return false;
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/link_device_medialive_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/link-device-medialive-input", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | label: data.scheme,
23 | data: data,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "Elemental Link to MediaLive Input";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediaconnect_flow_mediaconnect_flow.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/mediaconnect-flow-mediaconnect-flow", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | const human_type = data.scheme.replace("-", " ");
19 | items.push({
20 | id: connection.arn,
21 | to: connection.to,
22 | from: connection.from,
23 | data: data,
24 | label: human_type,
25 | arrows: "to",
26 | color: {
27 | color: "black",
28 | },
29 | dashes: false,
30 | });
31 | }
32 | resolve(items);
33 | });
34 | });
35 | };
36 |
37 | export const module_name = "MediaConnect Flow to MediaConnect Flow";
38 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediaconnect_flow_medialive_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/mediaconnect-flow-medialive-input", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | const human_type = data.scheme.replace(/_/, " ");
19 | items.push({
20 | id: connection.arn,
21 | to: connection.to,
22 | from: connection.from,
23 | data: data,
24 | label: human_type,
25 | arrows: "to",
26 | color: {
27 | color: "black",
28 | },
29 | dashes: false,
30 | });
31 | }
32 | resolve(items);
33 | });
34 | });
35 | };
36 |
37 | export const module_name = "MediaConnect Flow to MediaLive Input";
38 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = () => {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(`${url}/cached/medialive-channel-medialive-input`, api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.scheme,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | dashes: false,
29 | });
30 | }
31 | resolve(items);
32 | });
33 | });
34 | };
35 |
36 | export const module_name = "MediaLive Channel to MediaLive Input";
37 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_mediaconnect_flow.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = () => {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(`${url}/cached/medialive-channel-mediaconnect-flow`, api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.scheme,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | dashes: false,
29 | });
30 | }
31 | resolve(items);
32 | });
33 | });
34 | };
35 |
36 | export const module_name = "MediaLive Channel to MediaConnect Flow";
37 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_mediapackage_channel.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 | import { checkAdditionalConnections } from "./helper.js";
7 |
8 | export const update = () => {
9 | const current = connections.get_current();
10 | const url = current[0];
11 | const api_key = current[1];
12 | const items = [];
13 | return new Promise((resolve) => {
14 | server
15 | .get(
16 | `${url}/cached/medialive-channel-mediapackage-channel`,
17 | api_key
18 | )
19 | .then((results) => {
20 | for (const connection of results) {
21 | const data = JSON.parse(connection.data);
22 | const options = {
23 | id: connection.arn,
24 | to: connection.to,
25 | from: connection.from,
26 | data: data,
27 | label: "HLS",
28 | arrows: "to",
29 | color: { color: "black" },
30 | dashes: false,
31 | };
32 | const hasMoreConnections = checkAdditionalConnections(results, connection);
33 |
34 | if (hasMoreConnections.length) {
35 | /** curve it */
36 | options.smooth = { enabled: true };
37 | options.smooth.type = "discrete";
38 |
39 | if (_.has(data, "pipeline")) {
40 | options.label += ` ${data.pipeline}`;
41 | options.smooth.type =
42 | data.pipeline === 1 ? "curvedCCW" : "curvedCW";
43 | options.smooth.roundness = 0.15;
44 | }
45 | }
46 | items.push(options);
47 | }
48 | resolve(items);
49 | });
50 | });
51 | };
52 |
53 | export const module_name = "MediaLive Channel to MediaPackage Channel";
54 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_mediastore_container.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url + "/cached/medialive-channel-mediastore-container",
16 | api_key
17 | )
18 | .then((results) => {
19 | for (const connection of results) {
20 | const data = JSON.parse(connection.data);
21 | items.push({
22 | id: connection.arn,
23 | to: connection.to,
24 | from: connection.from,
25 | data: data,
26 | label: data.scheme + ":",
27 | arrows: "to",
28 | color: {
29 | color: "black",
30 | },
31 | dashes: false,
32 | });
33 | }
34 | resolve(items);
35 | });
36 | });
37 | };
38 |
39 | export const module_name = "MediaLive Channel to MediaStore Container";
40 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_multiplex.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 | import { checkAdditionalConnections } from "./helper.js";
7 |
8 | export const update = () => {
9 | const current = connections.get_current();
10 | const url = current[0];
11 | const api_key = current[1];
12 | const items = [];
13 | return new Promise((resolve) => {
14 | const endpoint = `${url}/cached/medialive-channel-multiplex`;
15 | server.get(endpoint, api_key).then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | const options = {
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.program,
24 | arrows: "to",
25 | color: { color: "black" },
26 | dashes: false,
27 | };
28 | const hasMoreConnections = checkAdditionalConnections(results, connection);
29 |
30 | if (hasMoreConnections.length) {
31 | /** curve it */
32 | options.smooth = { enabled: true };
33 | options.smooth.type = "discrete";
34 |
35 | if (_.has(data, "pipeline")) {
36 | options.label += ` ${data.pipeline}`;
37 | options.smooth.type =
38 | data.pipeline === 1 ? "curvedCCW" : "curvedCW";
39 | options.smooth.roundness = 0.15;
40 | }
41 | }
42 | items.push(options);
43 | }
44 | resolve(items);
45 | });
46 | });
47 | };
48 |
49 | export const module_name = "MediaLive Channel to Multiplex";
50 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_channel_s3_bucket.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/medialive-channel-s3-bucket", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.scheme,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | dashes: false,
29 | });
30 | }
31 | resolve(items);
32 | });
33 | });
34 | };
35 |
36 | export const module_name = "MediaLive Channels to S3 Buckets";
37 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/medialive_input_channel.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 | import { checkAdditionalConnections } from "./helper.js";
7 |
8 | export const update = function () {
9 | const current = connections.get_current();
10 | const url = current[0];
11 | const api_key = current[1];
12 | const items = [];
13 | return new Promise((resolve) => {
14 | server
15 | .get(url + "/cached/medialive-input-medialive-channel", api_key)
16 | .then((results) => {
17 | for (const connection of results) {
18 | const data = JSON.parse(connection.data);
19 | const options = {
20 | id: connection.arn,
21 | to: connection.to,
22 | from: connection.from,
23 | data: data,
24 | label: data.type.replace(/_/, " "),
25 | arrows: "to",
26 | color: { color: "black" },
27 | };
28 | const hasMoreConnections = checkAdditionalConnections(results, connection);
29 |
30 | if (hasMoreConnections.length) {
31 | /** curve it */
32 | options.smooth = { enabled: true };
33 | options.smooth.type = "discrete";
34 |
35 | if (_.has(data, "pipeline")) {
36 | options.label += ` ${data.pipeline}`;
37 | options.smooth.type =
38 | data.pipeline === 1 ? "curvedCCW" : "curvedCW";
39 | options.smooth.roundness = 0.15;
40 | }
41 | }
42 | items.push(options);
43 | }
44 | resolve(items);
45 | });
46 | });
47 | };
48 |
49 | export const module_name = "MediaLive Input to Channel Connections";
50 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediapackage_channel_endpoint.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url +
16 | "/cached/mediapackage-channel-mediapackage-origin-endpoint",
17 | api_key
18 | )
19 | .then((results) => {
20 | for (const connection of results) {
21 | const data = JSON.parse(connection.data);
22 | items.push({
23 | id: connection.arn,
24 | to: connection.to,
25 | from: connection.from,
26 | data: data,
27 | label: data.package,
28 | arrows: "to",
29 | color: {
30 | color: "black",
31 | },
32 | smooth: {
33 | enabled: true,
34 | type: "discrete",
35 | },
36 | });
37 | }
38 | resolve(items);
39 | });
40 | });
41 | };
42 |
43 | export const module_name = "MediaPackage Channel to Endpoint Connections";
44 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediapackage_endpoint_cloudfront.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url +
16 | "/cached/mediapackage-origin-endpoint-cloudfront-distribution",
17 | api_key
18 | )
19 | .then((results) => {
20 | for (const connection of results) {
21 | const data = JSON.parse(connection.data);
22 | items.push({
23 | id: connection.arn,
24 | to: connection.to,
25 | from: connection.from,
26 | data: data,
27 | label: data.scheme,
28 | arrows: "to",
29 | color: {
30 | color: "black",
31 | },
32 | });
33 | }
34 | resolve(items);
35 | });
36 | });
37 | };
38 |
39 | export const module_name = "MediaPackage Endpoints to CloudFront Distributions";
40 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediapackage_endpoint_mediatailor_configuration.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url +
16 | "/cached/mediapackage-origin-endpoint-mediatailor-configuration",
17 | api_key
18 | )
19 | .then((results) => {
20 | for (const connection of results) {
21 | const data = JSON.parse(connection.data);
22 | const human_type = data.scheme.replace(/_/, " ");
23 | items.push({
24 | id: connection.arn,
25 | to: connection.to,
26 | from: connection.from,
27 | data: data,
28 | label: human_type,
29 | arrows: "to",
30 | color: {
31 | color: "black",
32 | },
33 | });
34 | }
35 | resolve(items);
36 | });
37 | });
38 | };
39 |
40 | export const module_name = "MediaPackage Endpoint to MediaTailor Configuration";
41 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediastore_container_cloudfront.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url + "/cached/mediastore-container-cloudfront-distribution",
16 | api_key
17 | )
18 | .then((results) => {
19 | for (const connection of results) {
20 | const data = JSON.parse(connection.data);
21 | items.push({
22 | id: connection.arn,
23 | to: connection.to,
24 | from: connection.from,
25 | data: data,
26 | label: data.scheme,
27 | arrows: "to",
28 | color: {
29 | color: "black",
30 | },
31 | });
32 | }
33 | resolve(items);
34 | });
35 | });
36 | };
37 |
38 | export const module_name = "MediaStore Containers to CloudFront Distributions";
39 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediastore_container_medialive_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/mediastore-container-medialive-input", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.scheme + ":",
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "MediaStore Container to MediaLive Input";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/mediastore_container_mediatailor_configuration.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url + "/cached/mediastore-container-mediatailor-configuration",
16 | api_key
17 | )
18 | .then((results) => {
19 | for (const connection of results) {
20 | const data = JSON.parse(connection.data);
21 | items.push({
22 | id: connection.arn,
23 | to: connection.to,
24 | from: connection.from,
25 | data: data,
26 | label: data.scheme,
27 | arrows: "to",
28 | color: {
29 | color: "black",
30 | },
31 | });
32 | }
33 | resolve(items);
34 | });
35 | });
36 | };
37 |
38 | export const module_name = "MediaStore Container to MediaTailor Configurations";
39 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/multiplex_mediaconnect_flow.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/multiplex-mediaconnect-flow", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: "MEDIACONNECT",
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "Multiplex to MediaConnect Flow";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/s3_bucket_cloudfront.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/s3-bucket-cloudfront-distribution", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | data: data,
23 | label: data.label,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "S3 Buckets to CloudFront Distributions";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/s3_bucket_medialive_input.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/s3-bucket-medialive-input", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | label: data.scheme,
23 | data: data,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "S3 Buckets to MediaLive Inputs";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/s3_bucket_mediatailor_configuration.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(url + "/cached/s3-bucket-mediatailor-configuration", api_key)
15 | .then((results) => {
16 | for (const connection of results) {
17 | const data = JSON.parse(connection.data);
18 | items.push({
19 | id: connection.arn,
20 | to: connection.to,
21 | from: connection.from,
22 | label: data.scheme,
23 | data: data,
24 | arrows: "to",
25 | color: {
26 | color: "black",
27 | },
28 | });
29 | }
30 | resolve(items);
31 | });
32 | });
33 | };
34 |
35 | export const module_name = "S3 Buckets to MediaTailor Configurations";
36 |
--------------------------------------------------------------------------------
/source/html/js/app/mappers/connections/speke.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../../server.js";
5 | import * as connections from "../../connections.js";
6 |
7 | export const update = function () {
8 | const current = connections.get_current();
9 | const url = current[0];
10 | const api_key = current[1];
11 | const items = [];
12 | return new Promise((resolve) => {
13 | server
14 | .get(
15 | url + "/cached/mediapackage-origin-endpoint-speke-keyserver",
16 | api_key
17 | )
18 | .then((results) => {
19 | for (const connection of results) {
20 | const data = JSON.parse(connection.data);
21 | items.push({
22 | id: connection.arn,
23 | to: connection.to,
24 | from: connection.from,
25 | label: data.scheme,
26 | data: data,
27 | arrows: "to",
28 | color: {
29 | color: "black",
30 | },
31 | });
32 | }
33 | resolve(items);
34 | });
35 | });
36 | };
37 |
38 | export const module_name = "MediaPackage Origin Endpoint to SPEKE Keyserver";
39 |
--------------------------------------------------------------------------------
/source/html/js/app/model.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "./server.js";
5 | import * as connections from "./connections.js";
6 | import * as mappers from "./mappers/mappers.js";
7 |
8 | const nodes = new vis.DataSet();
9 | const edges = new vis.DataSet();
10 |
11 | const reset = function () {
12 | nodes.clear();
13 | edges.clear();
14 | };
15 |
16 | const map = function (callback) {
17 | new Promise(function (resolve) {
18 | const promises = [];
19 | for (const mapper of mappers.nodes) {
20 | console.log(mapper.module_name);
21 | promises.push(mapper.update());
22 | Promise.all(promises).then(function (resolved_values) {
23 | for (const items of resolved_values) {
24 | nodes.update(items);
25 | }
26 | resolve();
27 | });
28 | }
29 | })
30 | .then(function () {
31 | const promises = [];
32 | for (const mapper of mappers.connections) {
33 | console.log(mapper.module_name);
34 | promises.push(mapper.update());
35 | }
36 | Promise.all(promises).then(function (resolved_values) {
37 | for (const items of resolved_values) {
38 | edges.update(items);
39 | }
40 | for (const node of nodes.get()) {
41 | // add stringified tags to the node, will be used during search
42 | node.stringtags = JSON.stringify(node.data.Tags);
43 | nodes.update(node);
44 | }
45 | if (typeof callback !== "undefined") {
46 | callback();
47 | }
48 | });
49 | })
50 | .catch((error) => {
51 | console.error(error);
52 | });
53 | };
54 |
55 | const put_records = function (record) {
56 | const current = connections.get_current();
57 | const url = current[0];
58 | const api_key = current[1];
59 | const current_endpoint = `${url}/cached`;
60 | if (record && !Array.isArray(record)) {
61 | record = [record];
62 | }
63 | return new Promise(function (resolve, reject) {
64 | server
65 | .post(current_endpoint, api_key, record)
66 | .then(function (response) {
67 | console.log(response);
68 | resolve(response);
69 | })
70 | .catch(function (error) {
71 | console.error(error);
72 | reject(error);
73 | });
74 | });
75 | };
76 |
77 | const delete_record = function (arn) {
78 | const current = connections.get_current();
79 | const url = current[0];
80 | const api_key = current[1];
81 | const current_endpoint = `${url}/cached/arn/${encodeURIComponent(arn)}`;
82 | return new Promise(function (resolve, reject) {
83 | server
84 | .delete_method(current_endpoint, api_key)
85 | .then(function (response) {
86 | console.log(response);
87 | resolve(response);
88 | })
89 | .catch(function (error) {
90 | console.error(error);
91 | reject(error);
92 | });
93 | });
94 | };
95 |
96 | // clear the model at module definition
97 | reset();
98 |
99 | export { nodes, edges, reset, map, put_records, delete_record };
100 |
--------------------------------------------------------------------------------
/source/html/js/app/notes.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "./server.js";
5 | import * as connections from "./connections.js";
6 |
7 | const promise_get_closure = (endpoint, api_key) => {
8 | return function (resolve, reject) {
9 | server
10 | .get(endpoint, api_key)
11 | .then(function (response) {
12 | resolve(response);
13 | })
14 | .catch(function (error) {
15 | console.error(error);
16 | reject(error);
17 | });
18 | };
19 | };
20 |
21 | const get_resource_notes = function (arn) {
22 | const current_connection = connections.get_current();
23 | const url = current_connection[0];
24 | const api_key = current_connection[1];
25 | const current_endpoint = `${url}/notes/${encodeURIComponent(arn)}`;
26 | return new Promise(promise_get_closure(current_endpoint, api_key));
27 | };
28 |
29 | const get_all_resource_notes = function () {
30 | const current_connection = connections.get_current();
31 | const url = current_connection[0];
32 | const api_key = current_connection[1];
33 | const current_endpoint = `${url}/notes`;
34 | return new Promise(promise_get_closure(current_endpoint, api_key));
35 | };
36 |
37 | const update_resource_notes = function (arn, notes) {
38 | const current_connection = connections.get_current();
39 | const url = current_connection[0];
40 | const api_key = current_connection[1];
41 | const current_endpoint = `${url}/notes/${encodeURIComponent(arn)}`;
42 | return new Promise(function (resolve, reject) {
43 | server
44 | .post(current_endpoint, api_key, notes)
45 | .then(function (response) {
46 | resolve(response);
47 | })
48 | .catch(function (error) {
49 | console.error(error);
50 | reject(error);
51 | });
52 | });
53 | };
54 |
55 | const promise_delete_closure = (endpoint, api_key) => {
56 | return function (resolve, reject) {
57 | server
58 | .delete_method(endpoint, api_key)
59 | .then(function (response) {
60 | resolve(response);
61 | })
62 | .catch(function (error) {
63 | console.error(error);
64 | reject(error);
65 | });
66 | };
67 | };
68 |
69 | const delete_resource_notes = function (arn) {
70 | const current_connection = connections.get_current();
71 | const url = current_connection[0];
72 | const api_key = current_connection[1];
73 | const current_endpoint = `${url}/notes/${encodeURIComponent(arn)}`;
74 | return new Promise(promise_delete_closure(current_endpoint, api_key));
75 | };
76 |
77 | const delete_all_resource_notes = function () {
78 | const current_connection = connections.get_current();
79 | const url = current_connection[0];
80 | const api_key = current_connection[1];
81 | const current_endpoint = `${url}/notes`;
82 | return new Promise(promise_delete_closure(current_endpoint, api_key));
83 | };
84 |
85 | export {
86 | get_resource_notes,
87 | get_all_resource_notes,
88 | update_resource_notes,
89 | delete_resource_notes,
90 | delete_all_resource_notes
91 | };
92 |
--------------------------------------------------------------------------------
/source/html/js/app/regions.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "./server.js";
5 | import * as connections from "./connections.js";
6 |
7 | let available = [];
8 |
9 | const get_available = function () {
10 | return available;
11 | };
12 |
13 | export const refresh = _.memoize(function () {
14 | const current_connection = connections.get_current();
15 | const url = current_connection[0];
16 | const api_key = current_connection[1];
17 | const all_endpoint = `${url}/regions`;
18 | return new Promise(function (resolve, reject) {
19 | server
20 | .get(all_endpoint, api_key)
21 | .then(function (data) {
22 | available = data;
23 | available.sort(function (a, b) {
24 | const nameA = a.RegionName;
25 | const nameB = b.RegionName;
26 | if (nameA < nameB) {
27 | return -1;
28 | } else if (nameA > nameB) {
29 | return 1;
30 | } else {
31 | // names must be equal
32 | return 0;
33 | }
34 | });
35 | const module = {
36 | get_available: get_available,
37 | };
38 | resolve(module);
39 | })
40 | .catch(function (error) {
41 | console.error(error);
42 | reject(error);
43 | });
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/source/html/js/app/server.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | // default 60 second timeout
5 | let request_timeout = 60 * 1000;
6 |
7 | const get = function (url, api_key) {
8 | return new Promise((resolve, reject) => {
9 | const headers = {
10 | Accept: "application/json",
11 | "x-api-key": api_key,
12 | };
13 | // get the library contents
14 | $.ajax({
15 | url: url,
16 | type: "GET",
17 | headers: headers,
18 | success: (data) => {
19 | resolve(data);
20 | },
21 | error: (data) => {
22 | reject(data);
23 | },
24 | timeout: request_timeout,
25 | });
26 | });
27 | };
28 |
29 | const post = function (url, api_key, data) {
30 | return new Promise((resolve, reject) => {
31 | const headers = {
32 | Accept: "application/json",
33 | "x-api-key": api_key,
34 | };
35 | // get the library contents
36 | $.ajax({
37 | url: url,
38 | type: "POST",
39 | data: JSON.stringify(data),
40 | headers: headers,
41 | contentType: "application/json",
42 | success: (response) => {
43 | resolve(response);
44 | },
45 | error: (response) => {
46 | console.log(response);
47 | reject(response);
48 | },
49 | timeout: request_timeout,
50 | });
51 | });
52 | };
53 |
54 | const delete_method = function (url, api_key) {
55 | return new Promise((resolve, reject) => {
56 | const headers = {
57 | Accept: "application/json",
58 | "x-api-key": api_key,
59 | };
60 | // get the library contents
61 | $.ajax({
62 | url: url,
63 | type: "DELETE",
64 | headers: headers,
65 | contentType: "application/json",
66 | success: (data) => {
67 | resolve(data);
68 | },
69 | error: (data) => {
70 | console.log(data);
71 | reject(data);
72 | },
73 | timeout: request_timeout,
74 | });
75 | });
76 | };
77 |
78 | const delete_method_with_body = function (url, api_key, data) {
79 | return new Promise((resolve, reject) => {
80 | const headers = {
81 | Accept: "application/json",
82 | "x-api-key": api_key,
83 | };
84 | // get the library contents
85 | $.ajax({
86 | url: url,
87 | type: "DELETE",
88 | data: JSON.stringify(data),
89 | headers: headers,
90 | contentType: "application/json",
91 | success: (response) => {
92 | resolve(response);
93 | },
94 | error: (response) => {
95 | console.log(response);
96 | reject(response);
97 | },
98 | timeout: request_timeout,
99 | });
100 | });
101 | };
102 |
103 | export { get, post, delete_method, delete_method_with_body };
104 |
105 | export function get_request_timeout() {
106 | return request_timeout;
107 | }
108 |
109 | export function set_request_timeout(timeout) {
110 | request_timeout = timeout;
111 | }
112 |
--------------------------------------------------------------------------------
/source/html/js/app/settings.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "./server.js";
5 | import * as connections from "./connections.js";
6 |
7 | const get_setting = _.memoize(function (id) {
8 | // get the current connection data
9 | const current_connection = connections.get_current();
10 | const url = current_connection[0];
11 | const api_key = current_connection[1];
12 | // create the resource url
13 | const current_endpoint = `${url}/settings/${id}`;
14 | // return a promise that response with result
15 | return new Promise((resolve, reject) => {
16 | server
17 | .get(current_endpoint, api_key)
18 | .then((response) => {
19 | resolve(response);
20 | })
21 | .catch(function (error) {
22 | console.error(error);
23 | reject(error);
24 | });
25 | });
26 | });
27 |
28 | const put_setting = function (id, value) {
29 | // get the current connection data
30 | const current_connection = connections.get_current();
31 | const url = current_connection[0];
32 | const api_key = current_connection[1];
33 | // create the resource url
34 | const current_endpoint = `${url}/settings/${id}`;
35 | return new Promise((resolve, reject) => {
36 | const data = value;
37 | server
38 | .post(current_endpoint, api_key, data)
39 | .then((response) => {
40 | clear_function_cache();
41 | resolve(response);
42 | })
43 | .catch(function (error) {
44 | console.error(error);
45 | reject(error);
46 | });
47 | });
48 | };
49 |
50 | const remove_setting = function (id) {
51 | // get the current connection data
52 | const current_connection = connections.get_current();
53 | const url = current_connection[0];
54 | const api_key = current_connection[1];
55 | // create the resource url
56 | const current_endpoint = `${url}/settings/${id}`;
57 | return new Promise((resolve, reject) => {
58 | server
59 | .delete_method(current_endpoint, api_key)
60 | .then((response) => {
61 | clear_function_cache();
62 | resolve(response);
63 | })
64 | .catch(function (error) {
65 | console.error(error);
66 | reject(error);
67 | });
68 | });
69 | };
70 |
71 | const clear_function_cache = function () {
72 | get_setting.cache.clear();
73 | };
74 |
75 | export { get_setting as get, put_setting as put, remove_setting as remove };
76 |
--------------------------------------------------------------------------------
/source/html/js/app/tools/build_numbers.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as check from "../api_check.js";
5 | import * as build from "../build.js";
6 | import * as connections from "../connections.js";
7 |
8 | const module_name = "MSAM Build Numbers";
9 |
10 | const run_tool = function () {
11 | return new Promise(function (resolve) {
12 | const current_connection = connections.get_current();
13 | const endpoint = current_connection[0];
14 | const api_key = current_connection[1];
15 | const app_stamp = build.get_version();
16 | check
17 | .ping(endpoint, api_key)
18 | .then(function (response) {
19 | const message = `
20 | This tool shows the versions for the currently running browser application and the currently connected endpoint.
21 |
22 |
23 |
24 | # |
25 | Component |
26 | Version |
27 |
28 |
29 |
30 |
31 | 1 |
32 | Browser Application |
33 | ${app_stamp} |
34 |
35 |
36 | 2 |
37 | Endpoint API |
38 | ${response.version} |
39 |
40 |
41 |
42 | `;
43 | resolve({
44 | name: module_name,
45 | success: true,
46 | message: message,
47 | });
48 | })
49 | .catch(function (event) {
50 | resolve({
51 | name: module_name,
52 | success: false,
53 | message: "Error encountered: " + event,
54 | });
55 | });
56 | });
57 | };
58 |
59 | export { module_name as name, run_tool as run };
60 |
61 | export const requires_single_selection = false;
62 | export const requires_multi_selection = false;
63 | export const selection_id_regex = ".*";
64 |
--------------------------------------------------------------------------------
/source/html/js/app/tools/clear_http.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | const module_name = "HTTP Connections (Clear)";
5 |
6 | const run_tool = function () {
7 | return Promise.resolve({
8 | name: module_name,
9 | success: true,
10 | message:
11 | "This is a placeholder. This tool will find and show cloud resource interconnections that use HTTP (clear) instead of HTTPS (encrypted).",
12 | });
13 | };
14 |
15 | export { module_name as name, run_tool as run };
16 |
17 | export const requires_single_selection = false;
18 | export const requires_multi_selection = false;
19 | export const selection_id_regex = ".*";
20 |
--------------------------------------------------------------------------------
/source/html/js/app/tools/duplicate_names.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | const module_name = "Find Duplicate Named Services";
5 |
6 | const run_tool = function () {
7 | return Promise.resolve({
8 | name: module_name,
9 | success: false,
10 | message:
11 | "This is a placeholder. This tool will check names or IDs of services and warn on duplicates.",
12 | });
13 | };
14 |
15 | export { module_name as name, run_tool as run };
16 |
17 | export const requires_single_selection = false;
18 | export const requires_multi_selection = false;
19 | export const selection_id_regex = ".*";
20 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/alarm_indicators.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as model from "../model.js";
5 | import * as alarms from "../alarms.js";
6 | import * as diagrams from "./diagrams.js";
7 |
8 | function get_alarming_nodes(current_alarming_subscribers) {
9 | const alarming_nodes = [];
10 | for (const subscriber of current_alarming_subscribers) {
11 | const node = model.nodes.get(subscriber.ResourceArn);
12 | if (!node) {
13 | continue;
14 | }
15 | node.alarming = true;
16 | // track which nodes are signaling an alert
17 | if (!alarming_nodes.includes(subscriber.ResourceArn)) {
18 | alarming_nodes.push(subscriber.ResourceArn);
19 | const selected = node.render.alert_selected();
20 | const unselected = node.render.alert_unselected();
21 | // only update the node if the SVG changes
22 | if (
23 | selected != node.image.selected ||
24 | unselected != node.image.unselected
25 | ) {
26 | node.image.selected = selected;
27 | node.image.unselected = unselected;
28 | model.nodes.update(node);
29 | const matches = diagrams.have_all([node.id]);
30 | for (const diagram of matches) {
31 | diagram.nodes.update(node);
32 | diagram.alert(true);
33 | }
34 | }
35 | }
36 | }
37 | return alarming_nodes;
38 | }
39 |
40 | function get_inactive_nodes(previous_alarming_subscribers, alarming_nodes) {
41 | const inactive_nodes = [];
42 | for (const subscriber of previous_alarming_subscribers) {
43 | let found = false;
44 | for (const node_id of alarming_nodes) {
45 | found = found || node_id == subscriber.ResourceArn;
46 | }
47 | if (!found) {
48 | inactive_nodes.push(subscriber.ResourceArn);
49 | }
50 | }
51 | return inactive_nodes;
52 | }
53 |
54 | const updateAlarmState = function (
55 | current_alarming_subscribers,
56 | previous_alarming_subscribers
57 | ) {
58 | // iterate through current 'set' alerts
59 | const alarming_nodes = get_alarming_nodes(current_alarming_subscribers);
60 |
61 | // calculate the current alerts not included in the previous alerts
62 | const inactive_nodes = get_inactive_nodes(previous_alarming_subscribers, alarming_nodes);
63 |
64 | // 'unalert' the nodes that are no longer alerting
65 | for (const node_id of inactive_nodes) {
66 | const node = model.nodes.get(node_id);
67 | if (node) {
68 | node.alarming = false;
69 | // only switch the node render if the node is neither alarming nor alerting
70 | const selected = node.render.normal_selected();
71 | const unselected = node.render.normal_unselected();
72 | if (
73 | selected != node.image.selected ||
74 | unselected != node.image.unselected
75 | ) {
76 | node.image.selected = selected;
77 | node.image.unselected = unselected;
78 | model.nodes.update(node);
79 | const matches = diagrams.have_all([node.id]);
80 | for (const diagram of matches) {
81 | diagram.nodes.update(node);
82 | diagram.alert(false);
83 | }
84 | }
85 | }
86 | }
87 | };
88 |
89 | alarms.add_callback(updateAlarmState);
90 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/alert.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | const timeout = 5000;
5 |
6 | const div_id = "alert_div";
7 |
8 | export const show = function (message) {
9 | $("#" + div_id).html(message);
10 | $("#" + div_id).fadeIn("slow");
11 | setTimeout(function () {
12 | $("#" + div_id).fadeOut("slow");
13 | }, timeout);
14 | };
15 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/confirmation.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | export const show = function (html, on_proceed) {
5 | $("#confirmation_dialog_proceed").on("click", function (event) {
6 | console.log(event);
7 | on_proceed();
8 | $("#confirmation_dialog").modal("hide");
9 | });
10 | $("#confirmation_dialog").on("hide.bs.modal", function (event) {
11 | console.log(event);
12 | $("#confirmation_dialog_proceed").unbind("click");
13 | });
14 | $("#confirmation_dialog_body").html(html);
15 | $("#confirmation_dialog").modal("show");
16 | };
17 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/help_menu.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as build_numbers from "../tools/build_numbers.js";
5 |
6 | const show_result = (success, message) => {
7 | const alert_class = success ? "alert-success" : "alert-danger";
8 | const prefix = success ? "" : "Failed: ";
9 | const html = `${prefix}MSAM Version
`;
10 | $("#tool_output_modal_title").html(html);
11 | $("#tool_output_modal_message").html(message);
12 | $("#tool_output_modal").modal("show");
13 | };
14 |
15 | $("#build-version-button").on("click", function () {
16 | build_numbers
17 | .run()
18 | .then(function (result) {
19 | show_result(result.success, result.message);
20 | })
21 | .catch(function (error) {
22 | show_result(false, error);
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/information_compartment.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as settings from "../settings.js";
5 |
6 | let compartment_state = "max";
7 | const settings_key = "info-compartment-state";
8 |
9 | $("#information-compartment-up-down-button").click(() => {
10 | try {
11 | if (compartment_state === "min") {
12 | maximize_compartment();
13 | } else if (compartment_state === "max") {
14 | minimize_compartment();
15 | }
16 | } catch (error) {
17 | console.log(error);
18 | }
19 | $("#information-compartment-up-down-button").blur();
20 | });
21 |
22 | const maximize_compartment = () => {
23 | $("#information").fadeToggle("fast");
24 | $("#information-compartment-flex").fadeToggle("fast");
25 | $("#info-nav-flex").removeClass("border-bottom");
26 | $("#diagram").animate({ height: "-=28%" });
27 | compartment_state = "max";
28 | settings.put(settings_key, { state: compartment_state });
29 | };
30 |
31 | const minimize_compartment = () => {
32 | $("#information").fadeToggle("fast");
33 | $("#information-compartment-flex").fadeToggle("fast");
34 | $("#info-nav-flex").addClass("border-bottom");
35 | $("#diagram").animate({ height: "+=28%" });
36 | compartment_state = "min";
37 | settings.put(settings_key, { state: compartment_state });
38 | };
39 |
40 | const restore_state = async () => {
41 | try {
42 | const value = await settings.get(settings_key);
43 | console.log(`saved info compartment state = ${JSON.stringify(value)}`);
44 | if (value === null) {
45 | // no setting, keep the default state of maximized
46 | settings.put(settings_key, { state: "max" });
47 | } else if (value.state === "max") {
48 | // do nothing, default state
49 | } else if (value.state === "min") {
50 | minimize_compartment();
51 | }
52 | } catch (error) {
53 | console.log(JSON.stringify(error));
54 | }
55 | };
56 |
57 | // initialization
58 | restore_state();
59 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/informational_overlays.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as model from "../model.js";
5 | import * as overlays from "./overlays/overlays.js";
6 | import * as diagrams from "./diagrams.js";
7 |
8 | let intervalID;
9 | // interval in millis to update the cache
10 | const update_interval = 5000;
11 |
12 | function handle_node(node) {
13 | let selected = node.render.normal_selected();
14 | let unselected = node.render.normal_unselected();
15 |
16 | if (node.degraded) {
17 | selected = node.render.degraded_selected();
18 | unselected = node.render.degraded_unselected();
19 | } else if (node.alerting || node.alarming) {
20 | selected = node.render.alert_selected();
21 | unselected = node.render.alert_unselected();
22 | }
23 |
24 | // only update the node if the SVG changes
25 | if (
26 | selected != node.image.selected ||
27 | unselected != node.image.unselected
28 | ) {
29 | node.image.selected = selected;
30 | node.image.unselected = unselected;
31 | model.nodes.update(node);
32 |
33 | const matches = diagrams.have_all([node.id]);
34 |
35 | for (const diagram of matches) {
36 | diagram.nodes.update(node);
37 | }
38 | }
39 | }
40 |
41 | const update_overlay = function () {
42 | // console.log("info overlay update");
43 | // get all the overlays
44 | for (const ov of overlays.all) {
45 | if (!ov.informational) {
46 | continue;
47 | }
48 | const nodes = model.nodes.get({
49 | filter: (item) => {
50 | return (
51 | ov.match_type == (item.generic_node_type || item.title)
52 | );
53 | },
54 | });
55 |
56 | for (const node of nodes) {
57 | handle_node(node);
58 | }
59 | }
60 | };
61 |
62 | const schedule_interval = function () {
63 | if (intervalID) {
64 | clearInterval(intervalID);
65 | }
66 | intervalID = setInterval(update_overlay, update_interval);
67 | console.log(
68 | "informational overlays: interval scheduled " +
69 | update_interval +
70 | "ms, intervalID = " +
71 | intervalID
72 | );
73 | };
74 |
75 | schedule_interval();
76 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/layout.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as server from "../server.js";
5 | import * as connections from "../connections.js";
6 | import * as alert from "./alert.js";
7 |
8 | const retrieve_layout = function (diagram) {
9 | const current_connection = connections.get_current();
10 | const url = current_connection[0];
11 | const api_key = current_connection[1];
12 | const current_endpoint = `${url}/layout/view/${encodeURIComponent(
13 | diagram.view_id
14 | )}`;
15 | return server.get(current_endpoint, api_key);
16 | };
17 |
18 | const delete_layout = function (diagram, node_ids) {
19 | node_ids = node_ids || diagram.nodes.getIds();
20 | alert.show("Deleting layout");
21 | const current_connection = connections.get_current();
22 | const url = current_connection[0];
23 | const api_key = current_connection[1];
24 | for (const node_id of node_ids) {
25 | const current_endpoint = `${url}/layout/nodes/${encodeURIComponent(
26 | diagram.view_id
27 | )}/${encodeURIComponent(node_id)}`;
28 | server.delete_method(current_endpoint, api_key);
29 | }
30 | };
31 |
32 | const save_layout = function (diagram, node_ids) {
33 | node_ids = node_ids || diagram.nodes.getIds();
34 | alert.show("Saving layout");
35 | const network = diagram.network;
36 | const positions = network.getPositions(node_ids);
37 | const layout = [];
38 | for (const key of Object.keys(positions)) {
39 | const entry = {
40 | view: diagram.view_id,
41 | id: key,
42 | x: positions[key].x,
43 | y: positions[key].y,
44 | };
45 | layout.push(entry);
46 | }
47 | const current_connection = connections.get_current();
48 | const url = current_connection[0];
49 | const api_key = current_connection[1];
50 | const current_endpoint = `${url}/layout/nodes`;
51 | server
52 | .post(current_endpoint, api_key, layout)
53 | .then(function () {
54 | alert.show("Layout saved");
55 | console.log("layout changes are saved");
56 | })
57 | .catch(function (error) {
58 | console.error(error);
59 | });
60 | };
61 |
62 | function delete_all() {
63 | const current_connection = connections.get_current();
64 | const url = current_connection[0];
65 | const api_key = current_connection[1];
66 | const current_endpoint = `${url}/layout/views`;
67 | return new Promise((resolve, reject) => {
68 | server
69 | .delete_method(current_endpoint, api_key)
70 | .then((response) => {
71 | resolve(response);
72 | })
73 | .catch(function (error) {
74 | console.error(error);
75 | reject(error);
76 | });
77 | });
78 | }
79 |
80 | export { retrieve_layout, delete_layout, save_layout, delete_all };
81 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/nodes_menu.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as ui_util from "./util.js";
5 | import * as layout from "./layout.js";
6 | import * as alert from "./alert.js";
7 | import * as diagrams from "./diagrams.js";
8 |
9 | $("#nodes_layout_vertical").on("click", function () {
10 | const shown = diagrams.shown();
11 | if (shown) {
12 | shown.layout_vertical(true);
13 | }
14 | });
15 |
16 | $("#nodes_layout_horizontal").on("click", function () {
17 | const shown = diagrams.shown();
18 | if (shown) {
19 | shown.layout_horizontal(true);
20 | }
21 | });
22 |
23 | $("#nodes_layout_isolated").on("click", function () {
24 | const shown = diagrams.shown();
25 | if (shown) {
26 | shown.layout_isolated(true);
27 | }
28 | });
29 |
30 | $("#nodes_select_downstream").on("click", function () {
31 | const shown = diagrams.shown();
32 | if (shown) {
33 | const selected = shown.network.getSelectedNodes();
34 | const connected = [];
35 | for (const node_id of selected) {
36 | if (!connected.includes(node_id)) {
37 | connected.push(node_id);
38 | ui_util.get_downstream(shown.edges, node_id, connected);
39 | }
40 | }
41 | console.log(connected);
42 | alert.show(connected.length + " selected");
43 | shown.network.selectNodes(connected);
44 | }
45 | });
46 |
47 | $("#nodes_select_upstream").on("click", function () {
48 | const shown = diagrams.shown();
49 | if (shown) {
50 | const selected = shown.network.getSelectedNodes();
51 | const connected = [];
52 | for (const node_id of selected) {
53 | if (!connected.includes(node_id)) {
54 | connected.push(node_id);
55 | ui_util.get_upstream(shown.edges, node_id, connected);
56 | }
57 | }
58 | console.log(connected);
59 | alert.show(connected.length + " selected");
60 | shown.network.selectNodes(connected);
61 | }
62 | });
63 |
64 | $("#nodes_align_vertical").on("click", function () {
65 | const diagram = diagrams.shown();
66 | if (diagram) {
67 | const selected = diagram.network.getSelectedNodes();
68 | const positions = diagram.network.getPositions(selected);
69 | let average_x = 0;
70 | for (const node_id of Object.keys(positions)) {
71 | average_x += positions[node_id].x;
72 | }
73 | average_x = Math.round(average_x / selected.length);
74 | for (const node_id of Object.keys(positions)) {
75 | diagram.network.moveNode(node_id, average_x, positions[node_id].y);
76 | }
77 | layout.save_layout(diagram, Object.keys(positions));
78 | alert.show("Alignment complete");
79 | }
80 | });
81 |
82 | $("#nodes_align_horizontal").on("click", function () {
83 | const diagram = diagrams.shown();
84 | if (diagram) {
85 | const selected = diagram.network.getSelectedNodes();
86 | const positions = diagram.network.getPositions(selected);
87 | let average_y = 0;
88 | for (const node_id of Object.keys(positions)) {
89 | average_y += positions[node_id].y;
90 | }
91 | average_y = Math.round(average_y / selected.length);
92 | for (const node_id of Object.keys(positions)) {
93 | diagram.network.moveNode(node_id, positions[node_id].x, average_y);
94 | }
95 | layout.save_layout(diagram, Object.keys(positions));
96 | alert.show("Alignment complete");
97 | }
98 | });
99 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/alarms_only.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alarms from "../../alarms.js";
5 | import * as tools from "./overlay_tools.js";
6 |
7 | export const match_type = "Default Overlay for Alarms";
8 |
9 | const decorate_alarms = function (drawing, font_size, width, height, id) {
10 | let alarm_count = 0;
11 | for (const item of alarms.get_subscribers_with_alarms().current) {
12 | if (item.ResourceArn == id) {
13 | alarm_count += item.AlarmCount;
14 | }
15 | }
16 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
17 | };
18 |
19 | export const decorate = function (drawing, font_size, width, height, id) {
20 | decorate_alarms(drawing, font_size, width, height, id);
21 | };
22 |
23 | export const informational = false;
24 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/ec2_instance.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alarms from "../../alarms.js";
5 | import * as tools from "./overlay_tools.js";
6 | import * as model from "../../model.js";
7 |
8 | export const match_type = "EC2 Instance";
9 |
10 | const decorate_alarms = function (drawing, font_size, width, height, id) {
11 | let alarm_count = 0;
12 | for (const item of alarms.get_subscribers_with_alarms().current) {
13 | if (item.ResourceArn == id) {
14 | alarm_count += item.AlarmCount;
15 | }
16 | }
17 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
18 | };
19 |
20 | const decorate_information = function (drawing, font_size, width, height, id) {
21 | const node = model.nodes.get(id);
22 | if (node) {
23 | if (node.data.Tags.Name) {
24 | const computer_name = node.data.Tags.Name;
25 | tools.set_info_text(
26 | computer_name,
27 | drawing,
28 | font_size,
29 | width,
30 | "Name"
31 | );
32 | }
33 | }
34 | };
35 |
36 | export const decorate = function (drawing, font_size, width, height, id) {
37 | decorate_alarms(drawing, font_size, width, height, id);
38 | decorate_information(drawing, font_size, width, height, id);
39 | };
40 |
41 | export const informational = true;
42 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/mediaconnect_flow.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alert_events from "../../events.js";
5 | import * as alarms from "../../alarms.js";
6 | import * as tools from "./overlay_tools.js";
7 | import * as model from "../../model.js";
8 |
9 | export const match_type = "MediaConnect Flow";
10 |
11 | const decorate_alarms = function (drawing, font_size, width, height, id) {
12 | let alarm_count = 0;
13 | for (const item of alarms.get_subscribers_with_alarms().current) {
14 | if (item.ResourceArn == id) {
15 | alarm_count += item.AlarmCount;
16 | }
17 | }
18 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
19 | };
20 |
21 | const decorate_information = function (drawing, font_size, width, height, id) {
22 | const node = model.nodes.get(id);
23 | if (node) {
24 | let source_type = "Standard";
25 | if (node.data.Source.EntitlementArn) {
26 | source_type = "Entitlement";
27 | }
28 | else if (node.data.VpcInterfaces) {
29 | source_type = "VPC";
30 | }
31 | tools.set_info_text(source_type, drawing, font_size, width);
32 | }
33 | };
34 |
35 | const decorate_alerts = function (drawing, font_size, width, height, id) {
36 | let alert_count = 0;
37 | for (const item of alert_events.get_cached_events().current_mediaconnect) {
38 | if (item.resource_arn == id) {
39 | alert_count += 1;
40 | }
41 | }
42 | tools.set_event_text(alert_count, drawing, font_size, width, "Alerts");
43 | };
44 |
45 | export const decorate = function (drawing, font_size, width, height, id) {
46 | decorate_alarms(drawing, font_size, width, height, id);
47 | decorate_alerts(drawing, font_size, width, height, id);
48 | decorate_information(drawing, font_size, width, height, id);
49 | };
50 |
51 | export const informational = true;
52 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/medialive_channel.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alert_events from "../../events.js";
5 | import * as alarms from "../../alarms.js";
6 | import * as tools from "./overlay_tools.js";
7 |
8 | export const match_type = "MediaLive Channel";
9 |
10 | const decorate_alarms = function (drawing, font_size, width, height, id) {
11 | let alarm_count = 0;
12 | const cached_alarms = alarms.get_subscribers_with_alarms();
13 |
14 | for (const item of cached_alarms.current) {
15 | if (item.ResourceArn == id) {
16 | alarm_count += item.AlarmCount;
17 | }
18 | }
19 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
20 | };
21 |
22 | const decorate_events = function (drawing, font_size, width, height, id, data) {
23 | const isSinglePipeline = tools.has_single_pipeline(id, data);
24 | let pipeline_alerts = isSinglePipeline ? 0 : [0, 0];
25 | for (const item of alert_events.get_cached_events().current_medialive) {
26 | if (item.resource_arn == id) {
27 | if (isSinglePipeline) pipeline_alerts += 1;
28 | else pipeline_alerts[parseInt(item.detail.pipeline)] += 1;
29 | }
30 | }
31 |
32 | tools.set_event_text(pipeline_alerts, drawing, font_size, width);
33 | };
34 |
35 | export const decorate = function (drawing, font_size, width, height, id, data) {
36 | decorate_alarms(drawing, font_size, width, height, id);
37 | decorate_events(drawing, font_size, width, height, id, data);
38 | };
39 |
40 | export const informational = true;
41 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/medialive_multiplex.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alert_events from "../../events.js";
5 | import * as alarms from "../../alarms.js";
6 | import * as tools from "./overlay_tools.js";
7 |
8 | export const match_type = "MediaLive Multiplex";
9 |
10 | const decorate_alarms = function (drawing, font_size, width, height, id) {
11 | let alarm_count = 0;
12 | for (const item of alarms.get_subscribers_with_alarms().current) {
13 | if (item.ResourceArn == id) {
14 | alarm_count += item.AlarmCount;
15 | }
16 | }
17 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
18 | };
19 |
20 | const decorate_events = function (drawing, font_size, width, height, id, data) {
21 | const isSinglePipeline = tools.has_single_pipeline(id, data);
22 | let pipeline_alerts = isSinglePipeline ? 0 : [0, 0];
23 | for (const item of alert_events.get_cached_events().current_medialive) {
24 | if (item.resource_arn == id) {
25 | if (isSinglePipeline) pipeline_alerts += 1;
26 | else pipeline_alerts[parseInt(item.detail.pipeline)] += 1;
27 | }
28 | }
29 |
30 | tools.set_event_text(pipeline_alerts, drawing, font_size, width);
31 | };
32 |
33 | export const decorate = function (drawing, font_size, width, height, id, data) {
34 | decorate_alarms(drawing, font_size, width, height, id);
35 | decorate_events(drawing, font_size, width, height, id, data);
36 | };
37 |
38 | export const informational = true;
39 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/overlay_tools.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alert_events from "../../events.js";
5 |
6 | const info_y = 80;
7 | const event_y = 125;
8 | const alarm_y = 154;
9 | const generateText = (type, data) => `${type}: ${JSON.stringify(data)}`;
10 |
11 | const fetch_running_pipelines_count = (data) => {
12 | let pipelines_count = 0;
13 |
14 | if (_.has(data, "ChannelClass")) {
15 | if (data.ChannelClass === "STANDARD") pipelines_count = 2;
16 | else pipelines_count = 1;
17 | } else if (_.has(data, "Destinations"))
18 | pipelines_count = data.Destinations.length;
19 |
20 | return pipelines_count;
21 | };
22 |
23 | const has_single_pipeline = (id, data) => {
24 | const pipelines = {};
25 | let pipelines_count = 0;
26 |
27 | if (data) {
28 | if (
29 | _.has(data, "PipelinesRunningCount") &&
30 | data.PipelinesRunningCount > 1
31 | )
32 | return false;
33 |
34 | pipelines_count = fetch_running_pipelines_count(data);
35 |
36 | if (pipelines_count > 1) return false;
37 | }
38 |
39 | const cached_events = alert_events.get_cached_events();
40 |
41 | for (const item of cached_events.current_medialive) {
42 | if (item.resource_arn == id)
43 | pipelines[parseInt(item.detail.pipeline)] += 1;
44 | if (_.keys(pipelines).length > 1 && pipelines_count > 1) return false;
45 | }
46 |
47 | return true;
48 | };
49 |
50 | const draw_font_set_position = function (typeLabel, font_size, width) {
51 | typeLabel.font({ family: "Arial", size: font_size });
52 | typeLabel.cx(width / 2);
53 | };
54 |
55 | const set_alarm_text = function (data, drawing, font_size, width) {
56 | const typeLabel = drawing
57 | .text(generateText("Active alarms", data))
58 | .y(alarm_y);
59 | draw_font_set_position(typeLabel, font_size, width);
60 | };
61 |
62 | const set_event_text = function (
63 | data,
64 | drawing,
65 | font_size,
66 | width,
67 | text = "Pipeline alerts"
68 | ) {
69 | const typeLabel = drawing.text(generateText(text, data)).y(event_y);
70 | draw_font_set_position(typeLabel, font_size, width);
71 | };
72 |
73 | const set_info_text = function (
74 | data,
75 | drawing,
76 | font_size,
77 | width,
78 | label = "Type"
79 | ) {
80 | const typeLabel = drawing.text(generateText(label, data)).y(info_y);
81 | draw_font_set_position(typeLabel, font_size, width);
82 | };
83 |
84 | export { set_alarm_text, set_event_text, set_info_text, has_single_pipeline };
85 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/overlays.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as overlay_mediaconnect_flow from "./mediaconnect_flow.js";
5 | import * as overlay_medialive_channel from "./medialive_channel.js";
6 | import * as overlay_medialive_multiplex from "./medialive_multiplex.js";
7 | import * as overlay_ssm_managed_instance from "./ssm_managed_instance.js";
8 | import * as overlay_ec2_instance from "./ec2_instance.js";
9 | import * as overlay_alarms_only from "./alarms_only.js";
10 |
11 | export const all = [
12 | overlay_mediaconnect_flow,
13 | overlay_medialive_channel,
14 | overlay_medialive_multiplex,
15 | overlay_ssm_managed_instance,
16 | overlay_ec2_instance,
17 | ];
18 |
19 | export const default_overlay = overlay_alarms_only;
20 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/overlays/ssm_managed_instance.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as alarms from "../../alarms.js";
5 | import * as tools from "./overlay_tools.js";
6 | import * as model from "../../model.js";
7 |
8 | export const match_type = "SSM Managed Instance";
9 |
10 | const decorate_alarms = function (drawing, font_size, width, height, id) {
11 | let alarm_count = 0;
12 | for (const item of alarms.get_subscribers_with_alarms().current) {
13 | if (item.ResourceArn == id) {
14 | alarm_count += item.AlarmCount;
15 | }
16 | }
17 | tools.set_alarm_text(alarm_count, drawing, font_size, width);
18 | };
19 |
20 | const decorate_information = function (drawing, font_size, width, height, id) {
21 | const node = model.nodes.get(id);
22 | if (node) {
23 | if (node.data.Data["AWS:InstanceInformation"].Content[0].ComputerName) {
24 | const computer_name =
25 | node.data.Data["AWS:InstanceInformation"].Content[0]
26 | .ComputerName;
27 | tools.set_info_text(
28 | computer_name,
29 | drawing,
30 | font_size,
31 | width,
32 | "Name"
33 | );
34 | }
35 | }
36 | };
37 |
38 | export const decorate = function (drawing, font_size, width, height, id) {
39 | decorate_alarms(drawing, font_size, width, height, id);
40 | decorate_information(drawing, font_size, width, height, id);
41 | };
42 |
43 | export const informational = true;
44 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/status_view.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import * as model from "../model.js";
5 | import * as statemachine from "../statemachine.js";
6 |
7 | const current_tab = "";
8 | let progressTimer;
9 |
10 | const calculate_progress = function (fsm) {
11 | // get the total number of states for this FSM
12 | const states = Object.keys(fsm.states);
13 | // get our current position within the states
14 | const index = states.indexOf(fsm.state);
15 | // calculate the current state position as a percentage
16 | return Number.parseInt(((index + 1) / states.length) * 100);
17 | };
18 |
19 | const show = function () {
20 | if (typeof progressTimer === "undefined") {
21 | progressTimer = setTimeout(update, 500);
22 | }
23 | };
24 |
25 | const update = function () {
26 | const id = "#nav-status";
27 | const tab = id + "-tab";
28 | if (current_tab !== tab) {
29 | $(tab).tab("show");
30 | }
31 | const configuration_percent = calculate_progress(
32 | statemachine.getConfigurationStateMachine()
33 | );
34 | const model_data_percent = calculate_progress(
35 | statemachine.getModelDataStateMachine()
36 | );
37 | const configuration_class =
38 | configuration_percent < 100 ? "progress-bar-striped progress-bar-animated bg-warning" : "bg-success";
39 | const model_data_class =
40 | model_data_percent < 100 ? "progress-bar-striped progress-bar-animated bg-warning" : "bg-success";
41 | const configuration_stats =
42 | configuration_percent < 100 ? configuration_percent + "%" : "Ready";
43 | const model_stats = `${model.nodes.length} Nodes, ${model.edges.length} Connections`;
44 | const html = `
45 |
46 |
47 |
48 | Configuration |
49 |
50 |
51 | ${configuration_stats}
52 |
53 | |
54 |
55 |
56 | Model Contents |
57 |
58 |
61 | |
62 |
63 |
64 |
`;
65 | $(id).html(html);
66 | progressTimer = undefined;
67 | };
68 |
69 | model.nodes.on("add", function () {
70 | show();
71 | });
72 |
73 | model.edges.on("add", function () {
74 | show();
75 | });
76 |
77 | statemachine.getToolStateMachine().on("transition", function () {
78 | show();
79 | });
80 |
--------------------------------------------------------------------------------
/source/html/js/app/ui/util.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | export const makeid = function (id_len = 10) {
5 | let text = "";
6 | const possible =
7 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
8 | for (let i = 0; i < id_len; i++) {
9 | text += possible.charAt(get_random_number(possible.length));
10 | }
11 | return text;
12 | };
13 |
14 | export function get_random_number(max) {
15 | const randomBuffer = new Uint32Array(1);
16 | crypto.getRandomValues(randomBuffer);
17 | const randomNumber = randomBuffer[0] / (0xffffffff + 1);
18 | return Math.floor(randomNumber * (max));
19 | }
20 |
21 | export function vary(value, limit) {
22 | return (
23 | value + get_random_number(limit) * (get_random_number(2) == 0 ? -1 : 1)
24 | );
25 | }
26 |
27 | export const get_downstream = function (edges, node_id, connected_nodes) {
28 | const downstream_edges = edges.get({
29 | filter: function (item) {
30 | return item.from === node_id;
31 | },
32 | });
33 | for (const edge of downstream_edges) {
34 | if (!connected_nodes.includes(edge.to)) {
35 | connected_nodes.push(edge.to);
36 | get_downstream(edges, edge.to, connected_nodes);
37 | }
38 | }
39 | };
40 |
41 | export const get_upstream = function (edges, node_id, connected_nodes) {
42 | const upstream_edges = edges.get({
43 | filter: function (item) {
44 | return item.to === node_id;
45 | },
46 | });
47 | for (const edge of upstream_edges) {
48 | if (!connected_nodes.includes(edge.from)) {
49 | connected_nodes.push(edge.from);
50 | get_upstream(edges, edge.from, connected_nodes);
51 | }
52 | }
53 | };
54 |
--------------------------------------------------------------------------------
/source/html/js/test/alarms.test.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | /* eslint no-import-assign: "off" */
5 |
6 | import { jest } from '@jest/globals';
7 | import * as alarms from "../app/alarms.js";
8 | import * as server from "../app/server.js";
9 | import * as connections from "../app/connections.js";
10 |
11 | const internals = alarms.exported_for_unit_tests;
12 |
13 | afterEach(() => {
14 | jest.restoreAllMocks();
15 | });
16 |
17 | test('get_subscribers_with_alarms', () => {
18 | expect(alarms.get_subscribers_with_alarms()).toMatchObject({
19 | current: [],
20 | previous: [],
21 | }
22 | );
23 | });
24 |
25 | test('add_callback', () => {
26 | const caller = jest.fn();
27 | alarms.add_callback(caller);
28 | expect(internals.listeners).toContain(caller);
29 | });
30 |
31 | test('all_alarms_for_region', () => {
32 | connections.get_current = jest.fn(() => {
33 | return ["url", "api-key"];
34 | });
35 | server.get = jest.fn(() => {
36 | return Promise.resolve(true);
37 | });
38 | expect(alarms.all_alarms_for_region("us-west-2")).resolves.toBeTruthy();
39 | });
40 |
41 | test('subscribe_to_alarm', () => {
42 | connections.get_current = jest.fn(() => {
43 | return ["url", "api-key"];
44 | });
45 | server.post = jest.fn(() => {
46 | return Promise.resolve(true);
47 | });
48 | expect(alarms.subscribe_to_alarm("us-west-2", "TEST-ALARM", ["ARN-1", "ARN-2"])).resolves.toBeTruthy();
49 | });
50 |
51 | test('unsubscribe_to_alarm', () => {
52 | connections.get_current = jest.fn(() => {
53 | return ["url", "api-key"];
54 | });
55 | server.post = jest.fn(() => {
56 | return Promise.resolve(true);
57 | });
58 | expect(alarms.unsubscribe_from_alarm("us-west-2", "TEST-ALARM", ["ARN-1", "ARN-2"])).resolves.toBeTruthy();
59 | });
60 |
61 | test('alarms_for_subscriber', () => {
62 | connections.get_current = jest.fn(() => {
63 | return ["url", "api-key"];
64 | });
65 | server.get = jest.fn(() => {
66 | return Promise.resolve(true);
67 | });
68 | expect(alarms.alarms_for_subscriber("ARN-1")).resolves.toBeTruthy();
69 | });
70 |
71 | test('delete_all_subscribers', () => {
72 | connections.get_current = jest.fn(() => {
73 | return ["url", "api-key"];
74 | });
75 | server.delete_method = jest.fn(() => {
76 | return Promise.resolve(true);
77 | });
78 | expect(alarms.delete_all_subscribers()).resolves.toBeTruthy();
79 | });
80 |
81 | // set_update_interval
82 | // get_update_interval
83 |
--------------------------------------------------------------------------------
/source/html/js/test/always.test.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | // two simple checks of the testing framework
5 |
6 | test('always passes', () => {
7 | expect(true).toBe(true);
8 | });
9 |
10 | test('always passes', () => {
11 | expect("Test").toMatch("Test");
12 | });
13 |
--------------------------------------------------------------------------------
/source/html/js/test/api_check.test.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | /* eslint no-import-assign: "off" */
5 |
6 | import { jest } from '@jest/globals'
7 | import * as server from "../app/server.js";
8 | import * as api_check from "../app/api_check.js";
9 |
10 | afterEach(() => {
11 | jest.restoreAllMocks();
12 | });
13 |
14 | test('ping', () => {
15 | // mock the server.get module function
16 | server.get = jest.fn(() => { return "success" });
17 | expect(api_check.ping('fake-url', 'fake-api-key')).toBe("success");
18 | });
19 |
--------------------------------------------------------------------------------
/source/html/js/test/connections.test.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | SPDX-License-Identifier: Apache-2.0 */
3 |
4 | import { jest } from '@jest/globals';
5 | import * as connections from "../app/connections.js";
6 |
7 | const mock_cookies = {
8 | "MSAM_CURRENT": "MSAM_ENDPOINT_TEST",
9 | "MSAM_ENDPOINT_TEST": window.btoa(JSON.stringify({ name: "connection" }))
10 | };
11 |
12 | const mock_connections = {
13 | "MSAM_ENDPOINT_TEST": { name: "connection" }
14 | };
15 |
16 | // mock the Cookies global to return test cookies
17 | Cookies.get = jest.fn();
18 | Cookies.set = jest.fn();
19 |
20 | afterEach(() => {
21 | jest.restoreAllMocks();
22 | });
23 |
24 | test('get_remembered', () => {
25 | Cookies.get.mockReturnValue(mock_cookies)
26 | expect(connections.get_remembered()).toMatchObject([mock_connections["MSAM_ENDPOINT_TEST"]]);
27 | });
28 |
29 | test('get_current', () => {
30 | Cookies.get.mockReturnValueOnce(mock_cookies["MSAM_CURRENT"]);
31 | Cookies.get.mockReturnValueOnce(mock_cookies["MSAM_ENDPOINT_TEST"]);
32 | expect(connections.get_current()).toMatchObject(mock_connections["MSAM_ENDPOINT_TEST"]);
33 | });
34 |
--------------------------------------------------------------------------------
/source/html/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "license": "Apache-2.0",
3 | "description": "Media Services Application Mapper Browser Application",
4 | "version": "1.13.2",
5 | "dependencies": {
6 | "@fortawesome/fontawesome-free": "^5.15.4",
7 | "bootstrap": "^5.1.3",
8 | "bootstrap-datepicker": "^1.9.0",
9 | "core-js": "^3.23.4",
10 | "fuse.js": "^6.5.3",
11 | "jquery": "^3.6.0",
12 | "jqueryui": "^1.11.1",
13 | "js-cookie": "^2.0.2",
14 | "lodash": "^4.17.21",
15 | "lodash-es": "^4.17.21",
16 | "machina": "^4.0.2",
17 | "material-icons": "^1.10.5",
18 | "moment": "^2.29.2",
19 | "object-hash": "^2.2.0",
20 | "renderjson": "^1.4.0",
21 | "showdown": "^2.0.3",
22 | "svg.js": "^2.6.6",
23 | "tabulator-tables": "^4.9.3",
24 | "vis-network": "^9.1.0",
25 | "xss": "^1.0.11"
26 | },
27 | "scripts": {
28 | "test": "jest --runInBand"
29 | },
30 | "type": "module",
31 | "devDependencies": {
32 | "@babel/cli": "^7.18.6",
33 | "@babel/core": "^7.21.0",
34 | "@babel/preset-env": "^7.18.6",
35 | "babel-jest": "^28.1.3",
36 | "jest": "^28.1.3",
37 | "jest-environment-jsdom": "^28.1.3"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/source/msam/.chalice/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "api_gateway_stage": "msam",
3 | "version": "2.0",
4 | "app_name": "msam",
5 | "manage_iam_role": false,
6 | "iam_role_arn": "core-iam-role-arn",
7 | "autogen_policy": false,
8 | "lambda_timeout": 300,
9 | "lambda_memory_size": 2560,
10 | "environment_variables": {
11 | "ALARMS_TABLE_NAME": "media-services-application-mapper-channels",
12 | "BUILD_STAMP": "DEV_0_0_0",
13 | "CACHE_ITEM_TTL": "7200",
14 | "CHANNELS_TABLE_NAME": "media-services-application-mapper-channels",
15 | "CONTENT_TABLE_NAME": "media-services-application-mapper-content",
16 | "EVENTS_TABLE_NAME": "media-services-application-mapper-events",
17 | "LAYOUT_TABLE_NAME": "media-services-application-mapper-layout",
18 | "SETTINGS_TABLE_NAME": "media-services-application-mapper-settings",
19 | "CLOUDWATCH_EVENTS_TABLE_NAME": "media-services-application-mapper-cloudwatchevents",
20 | "NOTES_TABLE_NAME": "media-services-application-mapper-resourcenotes",
21 | "DELETE_NOTES_FUNCTION": "delete_notes_function",
22 | "SOLUTION_ID": "AwsSolution/SO0048/%%VERSION%%",
23 | "VERSION": "%%VERSION%%"
24 | }
25 | }
--------------------------------------------------------------------------------
/source/msam/.chalice/policy-dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [{
4 | "Action": [
5 | "mediapackage:List*",
6 | "mediapackage:Describe*",
7 | "medialive:List*",
8 | "medialive:Describe*",
9 | "mediastore:List*",
10 | "mediastore:Get*",
11 | "mediaconnect:List*",
12 | "mediaconnect:Describe*",
13 | "mediatailor:Get*",
14 | "mediatailor:List*",
15 | "ssm:List*",
16 | "ssm:Get*",
17 | "ssm:SendCommand"
18 | ],
19 | "Effect": "Allow",
20 | "Resource": "*"
21 | },
22 | {
23 | "Effect": "Allow",
24 | "Action": "ec2:Describe*",
25 | "Resource": "*"
26 | },
27 | {
28 | "Effect": "Allow",
29 | "Action": [
30 | "cloudwatch:ListMetrics",
31 | "cloudwatch:GetMetricStatistics",
32 | "cloudwatch:Describe*",
33 | "cloudwatch:PutMetricData"
34 | ],
35 | "Resource": "*"
36 | },
37 | {
38 | "Action": [
39 | "dynamodb:Query",
40 | "dynamodb:DeleteItem",
41 | "dynamodb:PutItem",
42 | "dynamodb:GetItem",
43 | "dynamodb:Scan"
44 | ],
45 | "Effect": "Allow",
46 | "Resource": "*"
47 | },
48 | {
49 | "Action": [
50 | "application-autoscaling:DescribeScalableTargets",
51 | "application-autoscaling:DescribeScalingActivities",
52 | "application-autoscaling:DescribeScalingPolicies",
53 | "cloudwatch:DescribeAlarmHistory",
54 | "cloudwatch:DescribeAlarms",
55 | "cloudwatch:DescribeAlarmsForMetric",
56 | "cloudwatch:GetMetricStatistics",
57 | "cloudwatch:ListMetrics",
58 | "ec2:DescribeVpcs",
59 | "ec2:DescribeSubnets",
60 | "ec2:DescribeSecurityGroups",
61 | "iam:GetRole",
62 | "iam:ListRoles",
63 | "sns:ListSubscriptions",
64 | "sns:ListSubscriptionsByTopic",
65 | "sns:ListTopics",
66 | "lambda:List*",
67 | "lambda:Get*"
68 | ],
69 | "Effect": "Allow",
70 | "Resource": "*"
71 | },
72 | {
73 | "Effect": "Allow",
74 | "Action": [
75 | "s3:Get*",
76 | "s3:List*"
77 | ],
78 | "Resource": "*"
79 | },
80 | {
81 | "Action": [
82 | "logs:CreateLogGroup",
83 | "logs:CreateLogStream",
84 | "logs:PutLogEvents",
85 | "logs:GetLogEvents"
86 | ],
87 | "Effect": "Allow",
88 | "Resource": "*"
89 | },
90 | {
91 | "Action": [
92 | "acm:ListCertificates",
93 | "cloudfront:Get*",
94 | "cloudfront:List*",
95 | "iam:ListServerCertificates",
96 | "route53:List*",
97 | "waf:ListWebACLs",
98 | "waf:GetWebACL"
99 | ],
100 | "Effect": "Allow",
101 | "Resource": "*"
102 | }
103 | ]
104 | }
--------------------------------------------------------------------------------
/source/msam/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | relative_files = True
3 | source = .
4 | omit = *test*
5 |
--------------------------------------------------------------------------------
/source/msam/.gitignore:
--------------------------------------------------------------------------------
1 | .chalice/deployments/
2 | .chalice/venv/
3 | __pycache__/
4 | db/package/
5 | build/msam-core-release.template
6 |
--------------------------------------------------------------------------------
/source/msam/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-solutions/media-services-application-mapper/9230ad89831347ae1a429935cf6619e6acad9107/source/msam/__init__.py
--------------------------------------------------------------------------------
/source/msam/chalicelib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-solutions/media-services-application-mapper/9230ad89831347ae1a429935cf6619e6acad9107/source/msam/chalicelib/__init__.py
--------------------------------------------------------------------------------
/source/msam/chalicelib/content.py:
--------------------------------------------------------------------------------
1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 | """
4 | This file contains helper functions related to the content DynamoDB table.
5 | """
6 |
7 | import os
8 |
9 | import boto3
10 | from botocore.config import Config
11 |
12 | # TTL provided via CloudFormation
13 | CACHE_ITEM_TTL = int(os.environ["CACHE_ITEM_TTL"])
14 |
15 | # table names generated by CloudFormation
16 | CONTENT_TABLE_NAME = os.environ["CONTENT_TABLE_NAME"]
17 |
18 | # user-agent config
19 | SOLUTION_ID = os.environ['SOLUTION_ID']
20 | USER_AGENT_EXTRA = {"user_agent_extra": SOLUTION_ID}
21 | MSAM_BOTO3_CONFIG = Config(**USER_AGENT_EXTRA)
22 |
23 | def put_ddb_items(items):
24 | """
25 | Add a list of cache items to the content (cache) DynamoDB table.
26 | """
27 | ddb_table_name = CONTENT_TABLE_NAME
28 | # shared resource and table
29 | ddb_resource = boto3.resource('dynamodb', config=MSAM_BOTO3_CONFIG)
30 | ddb_table = ddb_resource.Table(ddb_table_name)
31 | for item in items:
32 | ddb_table.put_item(Item=item)
33 | return True
34 |
--------------------------------------------------------------------------------
/source/msam/chalicelib/settings.py:
--------------------------------------------------------------------------------
1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 | """
4 | This file contains helper functions related to settings.
5 | """
6 |
7 | import os
8 | from urllib.parse import unquote
9 |
10 | import boto3
11 | from botocore.exceptions import ClientError
12 | from botocore.config import Config
13 |
14 | SETTINGS_TABLE_NAME = os.environ["SETTINGS_TABLE_NAME"]
15 |
16 | # user-agent config
17 | SOLUTION_ID = os.environ['SOLUTION_ID']
18 | USER_AGENT_EXTRA = {"user_agent_extra": SOLUTION_ID}
19 | MSAM_BOTO3_CONFIG = Config(**USER_AGENT_EXTRA)
20 |
21 | # DynamoDB
22 | DYNAMO_RESOURCE = boto3.resource("dynamodb", config=MSAM_BOTO3_CONFIG)
23 |
24 | def put_setting(key, value):
25 | """
26 | Put a string value into the setting table under key.
27 | """
28 | table = DYNAMO_RESOURCE.Table(SETTINGS_TABLE_NAME)
29 | # write to the database
30 | table.put_item(Item={"id": key, "value": value})
31 |
32 |
33 | def get_setting(key):
34 | """
35 | Retrieve a setting object from the database.
36 | """
37 | table = DYNAMO_RESOURCE.Table(SETTINGS_TABLE_NAME)
38 | # get the settings object
39 | setting = None
40 | try:
41 | response = table.get_item(Key={'id': key})
42 | # return the response or an empty object
43 | if "Item" in response:
44 | setting = response["Item"]["value"]
45 | else:
46 | setting = None
47 | except ClientError as error:
48 | print(error)
49 | return setting
50 |
51 |
52 | def application_settings(request, item_key):
53 | """
54 | API entry point to get or set the object value for a setting.
55 | """
56 | try:
57 | item_key = unquote(item_key)
58 | print(item_key)
59 | settings = {}
60 | print(request.method)
61 | if request.method in ('PUT', 'POST'):
62 | print(request.json_body)
63 | settings = request.json_body
64 | put_setting(item_key, settings)
65 | settings = {"message": "saved"}
66 | print(settings)
67 | elif request.method == 'GET':
68 | settings = get_setting(item_key)
69 | elif request.method == 'DELETE':
70 | table = DYNAMO_RESOURCE.Table(SETTINGS_TABLE_NAME)
71 | table.delete_item(Key={"id": item_key})
72 | except ClientError as error:
73 | # send the exception back in the object
74 | print(error)
75 | settings = {"exception": str(error)}
76 | return settings
77 |
--------------------------------------------------------------------------------
/source/msam/db/makezip.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | ORIGIN=`pwd`
7 | ZIP="$ORIGIN/dynamodb_resource.zip"
8 |
9 | rm -f $ZIP error.txt
10 | pip install --upgrade --force-reinstall --target ./package crhelper 2> error.txt
11 | RETVAL=$?
12 | if [ "$RETVAL" -ne "0" ]; then
13 | echo "ERROR: Database package installation failed."
14 | cat error.txt
15 | exit $RETVAL
16 | fi
17 | cd package
18 | zip -r9 $ZIP .
19 | cd $ORIGIN
20 | zip -g $ZIP lambda_function.py
21 |
--------------------------------------------------------------------------------
/source/msam/requirements.txt:
--------------------------------------------------------------------------------
1 | networkx
2 | jsonpath_ng
3 | stringcase
4 | requests
5 | defusedxml
6 | crhelper
7 | urllib3<2
8 |
--------------------------------------------------------------------------------
/source/msam/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-solutions/media-services-application-mapper/9230ad89831347ae1a429935cf6619e6acad9107/source/msam/test/__init__.py
--------------------------------------------------------------------------------
/source/msam/test/run_unit_tests.py:
--------------------------------------------------------------------------------
1 | """
2 | Launch from the source/msam/ folder:
3 | python -m test.run_unit_tests
4 |
5 | """
6 | import unittest
7 |
8 | # pylint: disable=W0611,E0611
9 | from test.test_cache import *
10 | from test.test_channels import *
11 | from test.test_cloudwatch import *
12 | from test.test_connections import *
13 | from test.test_layout import *
14 | from test.test_nodes import *
15 | from test.test_tags import *
16 | from test.test_content import *
17 | from test.test_notes import *
18 | from test.test_settings import *
19 | from test.test_periodic import *
20 | from test.test_app import *
21 | from test.test_db import *
22 |
23 | if __name__ == '__main__':
24 | unittest.main(verbosity=3)
25 |
--------------------------------------------------------------------------------
/source/msam/test/test_content.py:
--------------------------------------------------------------------------------
1 | """
2 | This module provides unit tests for the content.py module.
3 | """
4 |
5 | # pylint: disable=C0415,W0201
6 |
7 | import unittest
8 | from unittest.mock import patch
9 |
10 |
11 | @patch('os.environ')
12 | @patch('boto3.resource')
13 | @patch('boto3.client')
14 | class TestContent(unittest.TestCase):
15 | """
16 | This class extends TestCase with testing functions
17 | """
18 | def test_put_ddb_items(self, patched_env, patched_resource,
19 | patched_client):
20 | """
21 | Test the put_ddb_item function
22 | """
23 | from chalicelib import content
24 | content.put_ddb_items(["us-east-1"])
25 | content.boto3.resource.assert_called_once()
26 | content.boto3.resource.return_value.Table.assert_called_once_with('content_table')
27 | content.boto3.resource.return_value.Table.return_value.put_item.assert_called_once_with(Item='us-east-1')
28 | print()
29 |
--------------------------------------------------------------------------------
/source/msam/test/test_db.py:
--------------------------------------------------------------------------------
1 | """
2 | This module is provides unit tests for the db/lambda_function.py module.
3 | """
4 |
5 | # pylint: disable=C0415
6 |
7 | import unittest
8 | from unittest.mock import MagicMock, patch
9 | from botocore.exceptions import ClientError
10 |
11 | CLIENT_ERROR = ClientError({"Error": {"Code": "400", "Message": "SomeClientError"}}, "MockedFunction")
12 |
13 | @patch('os.environ')
14 | @patch('boto3.resource')
15 | @patch('boto3.client')
16 | class TestDb(unittest.TestCase):
17 | """
18 | This class extends TestCase with testing functions
19 | """
20 |
21 | def assertion_helper(self, lambda_function):
22 | """
23 | Helper function to run repetitive assertion statements
24 | """
25 | lambda_function.boto3.client.assert_called_once()
26 | lambda_function.boto3.client.return_value.describe_regions.assert_called_once_with()
27 | lambda_function.boto3.resource.assert_called_once()
28 | lambda_function.boto3.resource.return_value.Table.assert_called_once_with('settings_table')
29 | lambda_function.boto3.resource.return_value.Table.return_value.get_item.assert_called_once_with(Key={"id": "never-cache-regions"})
30 | self.assertEqual(lambda_function.boto3.resource.return_value.Table.return_value.put_item.call_count, 9)
31 |
32 | def test_create_update(self, patched_client, patched_resource, patched_env):
33 | """
34 | Test the create_udpate function
35 | """
36 | from db import lambda_function
37 | mocked_event = {"ResourceProperties": {"SettingsTable": "settings_table"}}
38 | lambda_function.create_update(mocked_event, MagicMock())
39 | self.assertion_helper(lambda_function)
40 |
41 |
42 | def test_lambda_handler(self, patched_client, patched_resource, patched_env):
43 | """
44 | Test the lambda_handler function
45 | """
46 | from db import lambda_function
47 | mocked_event = {"ResourceProperties": {"SettingsTable": "settings_table"}}
48 | with patch.object(lambda_function, 'helper'):
49 | lambda_function.lambda_handler(mocked_event, MagicMock())
50 | lambda_function.helper.assert_called_once()
51 |
52 | def test_make_default_settings(self, patched_client, patched_resource, patched_env):
53 | """
54 | Test the make_default_settings function
55 | """
56 | from db import lambda_function
57 | lambda_function.make_default_settings("settings_table")
58 | self.assertion_helper(lambda_function)
59 | lambda_function.boto3.client.reset_mock()
60 | lambda_function.boto3.resource.reset_mock()
61 |
62 | patched_resource.return_value.Table.return_value.put_item.side_effect = CLIENT_ERROR
63 | lambda_function.make_default_settings("settings_table")
64 | self.assertion_helper(lambda_function)
65 |
--------------------------------------------------------------------------------
/source/msam/test/test_settings.py:
--------------------------------------------------------------------------------
1 | """
2 | This module is provides unit tests for the settings.py module.
3 | """
4 |
5 | # pylint: disable=C0415,W0201
6 |
7 | import unittest
8 | from unittest.mock import patch, MagicMock
9 | from botocore.exceptions import ClientError
10 |
11 | KEY = 'key'
12 | VALUE = 'value'
13 | CLIENT_ERROR = ClientError({"Error": {"Code": "400", "Message": "SomeClientError"}}, "ClientError")
14 |
15 | @patch('os.environ')
16 | @patch('boto3.resource')
17 | @patch('boto3.client')
18 | class TestSettings(unittest.TestCase):
19 | """
20 | This class extends TestCase with testing functions
21 | """
22 |
23 | def setUp(self):
24 | from chalicelib import settings
25 | settings.DYNAMO_RESOURCE.reset_mock()
26 | settings.DYNAMO_RESOURCE.Table.return_value.put_item.reset_mock()
27 |
28 | def test_put_setting(self, patched_env, patched_resource,
29 | patched_client):
30 | """
31 | Test the put_setting function
32 | """
33 | from chalicelib import settings
34 | settings.put_setting(KEY, VALUE)
35 | settings.DYNAMO_RESOURCE.Table.return_value.put_item.assert_called_once_with(Item={"id": KEY, "value": VALUE})
36 |
37 | def test_get_setting(self, patched_env, patched_resource, patched_client):
38 | """
39 | Test the get_setting function
40 | """
41 | from chalicelib import settings
42 | settings.get_setting(KEY)
43 | settings.DYNAMO_RESOURCE.Table.return_value.get_item.assert_any_call(Key={'id': KEY})
44 |
45 | table_mock = MagicMock()
46 | table_mock.get_item.return_value = {"Item": {"value": VALUE}}
47 | with patch.object(settings.DYNAMO_RESOURCE, 'Table', return_value=table_mock):
48 | setting = settings.get_setting(KEY)
49 | settings.DYNAMO_RESOURCE.Table.return_value.get_item.assert_any_call(Key={'id': KEY})
50 | self.assertEqual(setting, 'value')
51 |
52 | with patch.object(settings.DYNAMO_RESOURCE.Table.return_value, 'get_item', side_effect=CLIENT_ERROR):
53 | setting = settings.get_setting(KEY)
54 | settings.DYNAMO_RESOURCE.Table.return_value.get_item.assert_any_call(Key={'id': KEY})
55 | self.assertEqual(setting, None)
56 |
57 |
58 | def test_application_settings(self, patched_env, patched_resource, patched_client):
59 | """
60 | Test the application_settings function
61 | """
62 | from chalicelib import settings
63 | mocked_req = MagicMock()
64 | mocked_req.method = "PUT"
65 | put_setting_mock = MagicMock()
66 | original_put_setting = settings.put_setting
67 | settings.put_setting = put_setting_mock
68 | settings.application_settings(mocked_req, KEY)
69 | settings.put_setting.assert_called_once()
70 | settings.put_setting = original_put_setting
71 | mocked_req.method = "DELETE"
72 | settings.application_settings(mocked_req, KEY)
73 | settings.DYNAMO_RESOURCE.Table.assert_called_once_with('settings_table')
74 | settings.DYNAMO_RESOURCE.Table.return_value.delete_item.assert_any_call(Key={'id': KEY})
75 | mocked_req.method = "GET"
76 | get_setting_mock = MagicMock()
77 | original_get_setting = settings.get_setting
78 | settings.get_setting = get_setting_mock
79 | settings.application_settings(mocked_req, KEY)
80 | settings.get_setting.assert_called_once()
81 | settings.get_setting = original_get_setting
82 | with patch.object(settings, 'get_setting', side_effect=CLIENT_ERROR):
83 | result = settings.application_settings(mocked_req, KEY)
84 | self.assertTrue("exception" in result)
85 |
--------------------------------------------------------------------------------
/source/tools/autopep8.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | autopep8 -i -a -a -r .
7 |
--------------------------------------------------------------------------------
/source/tools/copy_table.py:
--------------------------------------------------------------------------------
1 | """
2 | This program is responsible for copying DynamoDB tables,
3 | and is used for backups and migrations in MSAM.
4 | """
5 |
6 | import argparse
7 | import boto3
8 |
9 | def main():
10 | """
11 | This is the entry point for the program
12 | """
13 | try:
14 | parser = argparse.ArgumentParser(description='Copy database items from one DynamoDB table to another.')
15 | parser.add_argument('--source', required=True, help='source table name')
16 | parser.add_argument('--destination', required=True, help='destination table name')
17 | parser.add_argument('--region', default='us-west-2', help='the region where the tables reside (if not provided, default is us-west-2)')
18 | parser.add_argument('--profile', default='default', help='the AWS profile to use (if not provided, default profile is used)')
19 |
20 | args = parser.parse_args()
21 |
22 | session = boto3.Session(profile_name=args.profile, region_name=args.region)
23 | dynamo_resource = session.resource('dynamodb')
24 | source_table = dynamo_resource.Table(args.source)
25 | destination_table = dynamo_resource.Table(args.destination)
26 |
27 | scanned_items = []
28 | response = source_table.scan()
29 | if "Items" in response:
30 | scanned_items = response["Items"]
31 | while "LastEvaluatedKey" in response:
32 | response = source_table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
33 | if "Items" in response:
34 | scanned_items = scanned_items + response["Items"]
35 | #print(scanned_items)
36 |
37 | for item in scanned_items:
38 | destination_table.put_item(
39 | Item=item
40 | )
41 | except Exception as error:
42 | print(error)
43 |
44 |
45 | if __name__ == "__main__":
46 | main()
47 |
--------------------------------------------------------------------------------
/source/tools/create_test_alarms.py:
--------------------------------------------------------------------------------
1 | """
2 | This program generates CloudWatch Alarms to use with testing scale of MSAM.
3 | These are not valid alarms - they will not change state.
4 | """
5 |
6 | import copy
7 | import json
8 | import time
9 | import boto3
10 |
11 | ALARM_TEMPLATE = {
12 | "AlarmName": "1193839-0 Active Alerts",
13 | "AlarmDescription": "1193839-0 Active Alerts",
14 | "ActionsEnabled": True,
15 | "OKActions": [
16 | ],
17 | "AlarmActions": [
18 | ],
19 | "InsufficientDataActions": [],
20 | "MetricName": "ActiveAlerts",
21 | "Namespace": "MediaLive",
22 | "Statistic": "Maximum",
23 | "Dimensions": [{
24 | "Name": "ChannelId",
25 | "Value": "1193839"
26 | },
27 | {
28 | "Name": "Pipeline",
29 | "Value": "0"
30 | }
31 | ],
32 | "Period": 10,
33 | "EvaluationPeriods": 1,
34 | "DatapointsToAlarm": 1,
35 | "Threshold": 1.0,
36 | "ComparisonOperator": "GreaterThanOrEqualToThreshold",
37 | "TreatMissingData": "missing"
38 | }
39 |
40 | TOTAL_ALARMS = 500
41 |
42 | client = boto3.client("cloudwatch")
43 | for index in range(TOTAL_ALARMS):
44 | print(index)
45 | alarm_configuration = copy.deepcopy(ALARM_TEMPLATE)
46 | alarm_configuration["AlarmName"] = f"MSAM Test Alarm {time.time()}"
47 | alarm_configuration["AlarmDescription"] = "MSAM Testing Only, Do Not Use"
48 | print(json.dumps(alarm_configuration))
49 | response = client.put_metric_alarm(**alarm_configuration)
50 | print(json.dumps(response))
51 | time.sleep(0.25)
52 |
--------------------------------------------------------------------------------
/source/tools/create_test_alarms.sh:
--------------------------------------------------------------------------------
1 | AWS_PROFILE=personal AWS_DEFAULT_REGION=us-west-2 python create_test_alarms.py
2 |
--------------------------------------------------------------------------------
/source/tools/delete_disconnected.py:
--------------------------------------------------------------------------------
1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 | """
4 | This is a tool to clean nodes without connections from the content database table.
5 | """
6 |
7 | import os
8 | import sys
9 |
10 | import boto3
11 |
12 | CONNECTION_TYPES = [
13 | "cloudfront-distribution-medialive-input", "medialive-channel-mediapackage-channel", "medialive-channel-mediastore-container", "medialive-input-medialive-channel",
14 | "mediapackage-channel-mediapackage-origin-endpoint", "mediapackage-origin-endpoint-cloudfront-distribution", "mediastore-container-medialive-input", "s3-bucket-cloudfront-distribution",
15 | "s3-bucket-medialive-input", "mediapackage-origin-endpoint-speke-keyserver", "user-defined-connection"
16 | ]
17 | NODE_TYPES = ["s3", "cloudfront-distribution"]
18 |
19 | #
20 | # CONTENT_TABLE_NAME="IBC2018-DynamoDB-Content-17I5MRXA2FBF7" CACHE_ITEM_TTL=7200 python delete-disconnected.py
21 | #
22 |
23 |
24 | def delete_disconnected():
25 | """
26 | This function will clean nodes without connections from the content database table.
27 | """
28 | node_type = "S3"
29 | nodes = []
30 | connections = []
31 | for node_type in NODE_TYPES:
32 | nodes = nodes + cached_by_service(node_type)
33 | for conn_type in CONNECTION_TYPES:
34 | connections = connections + cached_by_service(conn_type)
35 | remove_nodes = []
36 | # scan for connections with 'to' or 'from' set with
37 | for node in nodes:
38 | found = False
39 | for conn in connections:
40 | if node["arn"] == conn["from"] or node["arn"] == conn["to"]:
41 | found = True
42 | if not found:
43 | remove_nodes.append(node)
44 |
45 | resource = boto3.resource("dynamodb")
46 | table = resource.Table(os.environ["CONTENT_TABLE_NAME"])
47 | for node in remove_nodes:
48 | print(node)
49 | table.delete_item(Key={"arn": node["arn"]})
50 |
51 |
52 | if __name__ == "__main__":
53 | sys.path.insert(0, '../api/msam')
54 | from chalicelib.cache import cached_by_service
55 | delete_disconnected()
56 |
--------------------------------------------------------------------------------
/source/tools/docker_msam_browser_app.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ ! -f index.html ]; then
4 | echo "*** index.html is not here, are you in the right place? ***"
5 | else
6 | docker stop msam-browser-app
7 | docker container rm msam-browser-app
8 | docker run --name msam-browser-app -v `pwd`:/var/www/html:ro -d -p 38080:80 public.ecr.aws/ubuntu/nginx:latest
9 | fi
10 |
--------------------------------------------------------------------------------
/source/tools/js-beautify.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | find . -iname '*js' -type f -print | xargs -n 1 js-beautify -r
7 |
--------------------------------------------------------------------------------
/source/tools/js-check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # http://www.apache.org/licenses/LICENSE-2.0
4 | #
5 | # Unless required by applicable law or agreed to in writing,
6 | # software distributed under the License is distributed on an
7 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 | # KIND, either express or implied. See the License for the
9 | # specific language governing permissions and limitations
10 | # under the License.
11 |
12 | # Run this from the root of the html folder
13 |
14 | set -euo pipefail
15 |
16 | if [ ! -f index.html ]; then
17 | echo "*** index.html is not here, are you in the right place? ***"
18 | else
19 | echo
20 | echo =========================
21 | echo JSHINT OUTPUT
22 | echo =========================
23 |
24 | find js/app -name '*.js' -type f -print | xargs jshint
25 |
26 | echo
27 | echo =========================
28 | echo ESLINT OUTPUT
29 | echo =========================
30 |
31 | eslint js/app
32 |
33 | echo
34 | fi
35 |
--------------------------------------------------------------------------------
/source/tools/jshint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # http://www.apache.org/licenses/LICENSE-2.0
4 | #
5 | # Unless required by applicable law or agreed to in writing,
6 | # software distributed under the License is distributed on an
7 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 | # KIND, either express or implied. See the License for the
9 | # specific language governing permissions and limitations
10 | # under the License.
11 |
12 | # Run this from the root of the html folder
13 |
14 | set -euo pipefail
15 |
16 | find . -name '*.js' -type f -print | \
17 | grep --invert-match "/external/" | \
18 | xargs -n 1 jshint
19 |
--------------------------------------------------------------------------------
/source/tools/jslint-report.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | find . -name '*js' -type f -print | xargs -n 1 jslint --browser --long --predef define --fudge --white --edition es6 > jslint-report.txt
7 |
--------------------------------------------------------------------------------
/source/tools/pa11y.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail",
4 | "WCAG2AA.Principle1.Guideline1_4.1_4_3.G145.Fail"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/source/tools/pylint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # http://www.apache.org/licenses/LICENSE-2.0
4 | #
5 | # Unless required by applicable law or agreed to in writing,
6 | # software distributed under the License is distributed on an
7 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 | # KIND, either express or implied. See the License for the
9 | # specific language governing permissions and limitations
10 | # under the License.
11 |
12 | # IGNORED RULES
13 | # E0401 Unable to import module (packaged via Lambda layers instead)
14 | # C0103 Constant name
15 | # C0301 Line too long
16 | # C0302 Too many lines in module
17 | # C0303 Trailing whitespace
18 | # C0411 Order of import
19 | # C0412 Grouping of import
20 | # C0413 Wrong import position (in unit tests)
21 | # R0201 Method could be a function (in unit tests)
22 | # R0801 Similar lines in files
23 | # R1702 Too many nested blocks
24 | # R0912 Too many branches
25 | # R0913 Too many arguments
26 | # R0914 Too many local variables
27 | # R0915 Too many statements
28 | # W0105 No effect string (comment in test)
29 | # W0401 Wildcard import
30 | # W0603 Global statement
31 | # W0621 Redefining name
32 | # W0703 Catching too general exception
33 | # W0613 Unused argument (like passing 'event' or 'context' into lambda)
34 | # W0640 Cell variable
35 |
36 | set -euo pipefail
37 |
38 | find . -iname '*.py' | \
39 | grep "/package/" --invert-match | \
40 | grep "/.aws-sam/" --invert-match | \
41 | xargs pylint -d E0401,C0103,C0301,C0302,C0303,C0411,C0412,C0413,R0201,R0801,R1702,R0912,R0913,R0914,R0915,W0105,W0401,W0703,W0603,W0613,W0621,W0640
42 |
--------------------------------------------------------------------------------
/source/tools/yapf.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # http://www.apache.org/licenses/LICENSE-2.0
4 | #
5 | # Unless required by applicable law or agreed to in writing,
6 | # software distributed under the License is distributed on an
7 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8 | # KIND, either express or implied. See the License for the
9 | # specific language governing permissions and limitations
10 | # under the License.
11 |
12 | find . -iname '*.py' -print0 | \
13 | xargs -0 yapf -i --style='{based_on_style: pep8, join_multiple_lines: true, column_limit: 200, indent_width: 4}'
14 |
--------------------------------------------------------------------------------
/source/web-cloudformation/.gitignore:
--------------------------------------------------------------------------------
1 | package/
2 | *.zip
--------------------------------------------------------------------------------
/source/web-cloudformation/cfn_invalidate_resource.py:
--------------------------------------------------------------------------------
1 | """
2 | This custom resource is responsible for issuing an
3 | invalidation to CloudFront after the web content is changed.
4 | """
5 |
6 | import logging
7 | import time
8 |
9 | import boto3
10 | from crhelper import CfnResource
11 |
12 | logger = logging.getLogger(__name__)
13 | helper = CfnResource()
14 |
15 |
16 | @helper.update
17 | def invalidate_on_update(event, _):
18 | """
19 | This function issues an invalidation command to CloudFront.
20 | """
21 | distribution_id = event['ResourceProperties']['DistributionId']
22 | cloudfront = boto3.client("cloudfront")
23 | response = cloudfront.create_invalidation(DistributionId=distribution_id,
24 | InvalidationBatch={
25 | 'Paths': {
26 | 'Quantity': 1,
27 | 'Items': [
28 | '/*',
29 | ]
30 | },
31 | 'CallerReference':
32 | str(int(time.time()))
33 | })
34 | logger.info(response)
35 |
36 |
37 | def handler(event, context):
38 | """
39 | This is the Lambda custom resource entry point.
40 | """
41 | helper(event, context)
42 |
--------------------------------------------------------------------------------
/source/web-cloudformation/makezip.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | ORIGIN=`pwd`
7 | ZIP="$ORIGIN/webcontent_resource.zip"
8 | HTML_ZIP=$1
9 |
10 |
11 |
12 | if [ -d "package" ]; then
13 | rm -rf package
14 | fi
15 |
16 | rm -f $ZIP
17 | rm -f error.txt
18 |
19 | pip install --force-reinstall --target ./package requests crhelper urllib3==1.26.18 2> error.txt
20 | RETVAL=$?
21 | if [ "$RETVAL" -ne "0" ]; then
22 | echo "ERROR: System package installation failed."
23 | cat error.txt
24 | exit $RETVAL
25 | fi
26 | cd package
27 | zip -r9 $ZIP .
28 | cd $ORIGIN
29 | zip -g $ZIP cfn_bucket_loader.py cfn_invalidate_resource.py $HTML_ZIP
30 | rm $HTML_ZIP
31 |
--------------------------------------------------------------------------------