Esempio n. 1
0
def lambda_handler(event, context):
    project_id = event["pathParameters"]["projectId"]
    logger.info(f"Got request for project {project_id}")

    configfile = f"{project_id}/config.json"
    statefile = f"{project_id}/terraform.tfstate"

    config = json.loads(read_key_or_default(configfile))
    project_name = config["name"]
    logger.info(f"Got request for {project_name} with id {project_id}")

    self_url = "https://" + event["requestContext"]["domainName"]

    # Get existing state or create new
    if event['httpMethod'] == "GET":
        logger.info("Type is GET, send state")
        data = read_key_or_default(statefile)
        if data == None:
            return create_response(
                f"No project exists, please visit {self_url}/project/new")
        else:
            return create_response(data.decode('utf-8'))

    # update
    if event['httpMethod'] == "POST":
        logger.info("Type is POST, save and send state")
        data = read_key_or_default(configfile)
        if data == None:
            return create_response(
                f"No project exists, please visit {self_url}/project/new")
        else:
            data = event["body"]
            write_key(statefile, data)
            return create_response(data)
Esempio n. 2
0
def lambda_handler(event, context):
    project_id = event["pathParameters"]["projectId"]
    logger.info(f"Got request for project {project_id}")

    configfile = f"{project_id}/config.json"
    statefile = f"{project_id}/terraform.tfstate"

    config = json.loads(read_key_or_default(configfile))
    project_name = config["name"]
    logger.info(f"Got request for {project_name} with id {project_id}")

    self_url = "https://" + event["requestContext"]["domainName"]

    # Get existing state or create new
    if event['httpMethod'] == "GET":
        logger.info("Type is GET, send state")
        config = json.loads(read_key_or_default(configfile))
        state = json.loads(read_key_or_default(statefile))
        if config == None:
            return create_response(
                f"No project exists, please visit {self_url}/project/new")
        else:
            metadata = get_tf_metadata(state)
            resources = get_tf_res(state)
            output = INFO_TEMPLATE.render(config=config,
                                          metadata=metadata,
                                          resources=resources,
                                          project_id=project_id,
                                          domain=DOMAIN,
                                          token=config["token"])
            return create_response(output, contenttype="text/html")
Esempio n. 3
0
def lambda_handler(event, context):
    project_id = event["pathParameters"]["projectId"]
    logger.info(f"Got request for project {project_id}")

    statefile = f"{project_id}/terraform.tfstate"
    self_url = "https://" + event["requestContext"]["domainName"]

    config = get_config(project_id)
    if config["name"] == "invalid":
        return create_response(
            f"No project exists, please visit {self_url}/project/new", 404)

    project_name = config["name"]
    logger.info(f"Got request for {project_name} with id {project_id}")

    # Get existing state or create new
    if event["httpMethod"] == "GET":
        logger.info("Type is GET, send state")
        data = read_key_or_default(statefile)
        return create_response(data.decode("utf-8"))

    # update
    if event["httpMethod"] == "POST":
        logger.info("Type is POST, save and send state")
        data = event["body"]
        metadata = get_tf_metadata(data, True)
        if metadata["terraform_version"] == "invalid":
            return create_response("Unable to parse", code=500)
        else:
            write_key(statefile, data)
            # todo: write the terraform.tfstate.serial
            return create_response(data)
Esempio n. 4
0
 def test_create(self):
     project_id = new_project(name="test", owner="*****@*****.**")
     raw_tf = read_key_or_default(f"{project_id}/terraform.tfstate",
                                  "EMPTY")
     config = get_config(project_id)
     self.assertTrue(raw_tf.startswith(b"{"))
     self.assertEqual(config["name"], "test")
Esempio n. 5
0
    def test_report(self):
        project_id = gen_test_project()

        report = gen_report(project_id)
        report_from_s3 = json.loads(
            read_key_or_default(f"{project_id}/report.json", ""))

        self.assertEqual(report["config"]["name"], "test")
        self.assertEqual(report_from_s3["config"]["name"], "test")
Esempio n. 6
0
 def test_request_post_complete(self):
     event = {
         "httpMethod": "POST",
         "body": "name=test&owner=test%40test.de",
     }
     result = lambda_handler(event, {})
     self.assertEqual(result["statusCode"], 301)
     project_id = result["headers"]["Location"].split("/")[-2]
     state = json.loads(
         read_key_or_default(f"{project_id}/terraform.tfstate", "NA"))
     self.assertEqual(state["serial"], 0)
     config = get_config(project_id)
     self.assertEqual(config["name"], "test")
Esempio n. 7
0
def lambda_handler(event, context):

    logger.info(event)
    logger.info(context)

    # decode user and password
    if not "Authorization" in event["headers"]:
        return create_policy("NONE", "Deny")
    auth_raw = event["headers"]["Authorization"].split(" ")[1]
    auth_obj = base64.b64decode(auth_raw).decode("utf-8").split(":")
    auth_user = auth_obj[0]
    auth_pass = auth_obj[1]

    arn = event["methodArn"]
    logger.info(f"Got auth request from {auth_user} for {arn}")

    # if a new reuqest, use the global key (TBD restrict the cli to the token)
    if auth_user == "admin":
        logger.info("Got request for admin")
        if auth_pass == KEY:
            logger.info("PW correct allow usage of new")
            return create_policy(auth_user, arn, "Allow")
        else:
            logger.warn("Admin key does not fit, reject")
            raise Exception('Unauthorized')

    # for state or info use the key from the project
    if event["resource"] == "/project/{projectId}/terraform.tfstate":
        logger.info("Got request for info or state")
        if auth_user == "token":
            project_id = event["pathParameters"]["projectId"]
            logger.info(f"Got request for project {project_id}")
            configfile = f"{project_id}/config.json"
            config = json.loads(read_key_or_default(configfile))
            project_name = config["name"]
            project_token = config["token"]
            logger.info(f"Got request for {project_name} with id {project_id}")
            if project_token == auth_pass:
                logger.info("Token fits the project ones, allow")
                return create_policy(project_id, arn, "Allow")
            else:
                logger.warn("Token does not fit, reject")
                raise Exception('Unauthorized')

    logger.error("Got invalid request, Deny")
    raise Exception('Unauthorized')
Esempio n. 8
0
    def test_request_post(self):
        # create project
        project_id = gen_test_project()

        # post state
        raw_tf = read_file("test_data/terraform.teststate")
        event = {
            "httpMethod": "POST",
            "body": raw_tf,
            "pathParameters": {
                "projectId": project_id
            },
            "requestContext": {
                "domainName": "test.local"
            },
        }
        result = lambda_handler(event, {})
        self.assertEqual(result["statusCode"], 200)
        self.assertTrue(result["body"].startswith("{"))

        s3_data = read_key_or_default(f"{project_id}/terraform.tfstate",
                                      "NONE")
        tf_meta = get_tf_metadata(s3_data, True)
        self.assertNotEqual(tf_meta["terraform_version"], "invalid")
Esempio n. 9
0
 def test_default(self):
     data = read_key_or_default("test_default.txt", "test_default")
     self.assertEqual(data, b"test_default")
Esempio n. 10
0
 def test_real(self):
     write_key("test_real.txt", "test_real")
     data = read_key_or_default("test_real.txt", "Failed")
     self.assertEqual(data, b"test_real")
Esempio n. 11
0
 def test_overwrite(self):
     write_key("test_overwrite.txt", "TextBefore")
     write_key("test_overwrite.txt", "test_overwrite")
     data = read_key_or_default("test_overwrite.txt", "Failed")
     self.assertEqual(data, b"test_overwrite")