Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: add STAC browser option #64

Merged
merged 4 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ A STAC API implementation using [stac-fastapi](https://github.com/stac-utils/sta
### [pgSTAC Titiler API](https://developmentseed.org/eoapi-cdk/#titilerpgstacapilambda-)
A complete dynamic tiling API using [titiler-pgstac](https://github.com/stac-utils/titiler-pgstac) to create dynamic mosaics of assets based on [STAC Search queries](https://github.com/radiantearth/stac-api-spec/tree/master/item-search). Packaged as a complete runtime for deployment with API Gateway and Lambda and fully integrated with the pgSTAC Database construct.

### [STAC browser](https://developmentseed.org/eoapi-cdk/#stacbrowser-)
A CDK construct to host a static [Radiant Earth STAC browser](https://github.com/radiantearth/stac-browser) on S3.

### [STAC Ingestor](https://developmentseed.org/eoapi-cdk/#stacingestor-)
An API for large scale STAC data ingestion and validation into a pgSTAC instance.

Expand Down
3 changes: 2 additions & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from "./bootstrapper";
export * from "./database";
export * from "./ingestor-api";
export * from "./stac-api";
export * from "./titiler-pgstac-api";
export * from "./titiler-pgstac-api";
export * from "./stac-browser";
113 changes: 113 additions & 0 deletions lib/stac-browser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { Stack, aws_s3 as s3, aws_s3_deployment as s3_deployment} from "aws-cdk-lib";
import { RemovalPolicy, CfnOutput } from "aws-cdk-lib";
import { PolicyStatement, ServicePrincipal, Effect } from "aws-cdk-lib/aws-iam";

import { Construct } from "constructs";
import { execSync } from "child_process";
import * as fs from 'fs';

export class StacBrowser extends Construct {

public bucket: s3.Bucket;
public bucketDeployment: s3_deployment.BucketDeployment;

constructor(scope: Construct, id: string, props: StacBrowserProps) {
super(scope, id);

const buildPath = this.buildApp(props.stacCatalogUrl, props.githubRepoTag);

this.bucket = new s3.Bucket(this, 'Bucket', {
accessControl: s3.BucketAccessControl.PRIVATE,
removalPolicy: RemovalPolicy.DESTROY,
})

this.bucket.addToResourcePolicy(new PolicyStatement({
sid: 'AllowCloudFrontServicePrincipal',
effect: Effect.ALLOW,
actions: ['s3:GetObject'],
principals: [new ServicePrincipal('cloudfront.amazonaws.com')],
resources: [this.bucket.arnForObjects('*')],
conditions: {
'StringEquals': {
'aws:SourceArn': props.cloudFrontDistributionArn
}
}
}));


this.bucketDeployment = new s3_deployment.BucketDeployment(this, 'BucketDeployment', {
emileten marked this conversation as resolved.
Show resolved Hide resolved
destinationBucket: this.bucket,
sources: [s3_deployment.Source.asset(buildPath)]
});

new CfnOutput(this, "bucket-name", {
exportName: `${Stack.of(this).stackName}-bucket-name`,
value: this.bucket.bucketName,
});

}

private buildApp(stacCatalogUrl: string, githubRepoTag: string): string {

// Define where to clone and build
const cloneDirectory = './stac-browser';
const githubRepoUrl = 'https://github.com/radiantearth/stac-browser.git';

// if `cloneDirectory` exists, delete it
if (fs.existsSync(cloneDirectory)) {
console.log(`${cloneDirectory} already exists, deleting...`)
execSync(`rm -rf ${cloneDirectory}`);
}

// Clone the repo
console.log(`Cloning ${githubRepoUrl} into ${cloneDirectory}`)
execSync(`git clone ${githubRepoUrl} ${cloneDirectory}`);
emileten marked this conversation as resolved.
Show resolved Hide resolved

// Check out the desired version
console.log(`Checking out version ${githubRepoTag}`)
execSync(`git checkout tags/${githubRepoTag}`, { cwd: cloneDirectory });

// Install the dependencies and build the application
console.log(`Installing dependencies`)
execSync('npm install', { cwd: cloneDirectory });

// Build the app with catalogUrl
console.log(`Building app with catalogUrl=${stacCatalogUrl} into ${cloneDirectory}`)
execSync(`npm run build -- --catalogUrl=${stacCatalogUrl}`, { cwd: cloneDirectory });

return './stac-browser/dist'

}


}

export interface StacBrowserProps {

/**
* STAC catalog URL
*/
readonly stacCatalogUrl: string;

/**
* Tag of the radiant earth stac-browser repo to use to build the app.
*/
readonly githubRepoTag: string;


/**
* The ARN of the cloudfront distribution that will be added to the bucket policy with read access.
*
* @default - No cloudfront distribution ARN. The bucket policy will not be modified.
*/
readonly cloudFrontDistributionArn?: string;

/**
* The name of the index document (e.g. "index.html") for the website. Enables static website
* hosting for this bucket.
*
* @default - No index document.
*/
readonly websiteIndexDocument?: string;

}
Loading