Wednesday, June 15, 2016

Find What Process is Running on a Port OSX

17:12:52 ~/data/github/dronze {feature/#58} $ lsof -i :8000
COMMAND   PID          USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    29680 claytongraham  143u  IPv6 0xb9a0c6ac4b96e77f      0t0  TCP *:irdmi (LISTEN)

Monday, June 13, 2016

Minimum Mongo Restore Permissions

So this would work to restore a single database: Backup
sudo mongodump -h localhost -d stuffdb --username restoreSingleDB --password Moon1234 \
  -o stuffdb.20160724.dump
Restore
db.addUser( {
    user: "restoreSingleDB",
    pwd: "Moon1234",
    roles: [ "readWrite", "userAdmin" ]
} )

mongorestore --db  --username restoreSingleDB --password Moon1234 /
So this would work to restore all databases including user data:
db.addUser( {
    user: "restoreAll",
    pwd: "Moon1234",
    roles: [ "readWriteAnyDatabase", "userAdminAnyDatabase" ]
} )

mongorestore --username restoreAll --password Moon1234 /

Sunday, June 05, 2016

Documenting a REST API

I have found that MkDocs is pretty good. I can integrate it into a CICD build with little effort. What was not obvious was best practices for writing API docs. So I create a template! Check it out:

Tickers V1


Gives the user access to the available tickers.

Path: /rest/v1/tickers

GET /tickers/ticker/{ticker}

@PreAuthorize("hasAuthority('api')")
@RequestMapping(path = "/ticker/{ticker}",
    method = RequestMethod.GET,
    produces = MediaType.APPLICATION_JSON_VALUE )

Params

Param Type Required Notes
ticker path YES

Info

Attribute Value Notes
hasAuthority api Must be an api user to make calls.
jwt Bearer Call must have valid bearer token.
consumes NONE
produces application/json Generates JSON response.

curl example

curl -X GET -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0NjUxNzQyNDMsImF1dGhvcml0aWVzIjpbImFwaSJdLCJzdWJqZWN0IjoiMTE0OTEwOTg2ODIzOTczNDcwMTE0QGdvb2dsZSIsImlhdCI6MTQ2NTE3MDY0M30._cTZ_8rp0Z19cvzAGhXsNqD879KL9rAp17TWI3Qs6mk" 
-H "Cache-Control: no-cache" "https://api.dronze.com/rest/v1/tickers/ticker/AAPL"

response

{
  "id": "569f2d8b67d02fd037e5cd5e",
  "type": "ticker",
  "labels": [
    "AAPL",
    "APPLE INC"
  ],
  "embedded": {
    "currency": "USD",
    "cusip": "037833100",
    "exchange": "NASDAQ",
    "industry": "Electronic Equipment",
    "isin": "US0378331005",
    "last_updated": "Sep 25, 2015 12:00:00 AM",
    "perma_ticker_id": 199059,
    "prior_tickers": "None",
    "related_tickers": "None",
    "sic": 3571,
    "ticker": "AAPL",
    "ticker_name": "APPLE INC",
    "ticker_sector": "Technology"
  }
}
view raw example_rest.md hosted with ❤ by GitHub

Subdomain CNAME with Cloudfront

Automation is good. It means less mistakes and simple cookbooks for runbooks and deployments. Here is a simple recipe for deploying a subdomain CNAME with cloudfront.
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Template Route53_CNAME. This uses the patameters to create a subdomain CNAME",
"Parameters" : {
"HostedZone" : {
"Type" : "String",
"Description" : "The DNS name of an existing Amazon Route 53 hosted zone",
"AllowedPattern" : "(?!-)[a-zA-Z0-9-.]{1,63}(?<!-)",
"ConstraintDescription" : "must be a valid DNS zone name."
},
"SubdomainParam": {
"Type": "String",
"Description": "Enter the subdomain name for the stack you want mapped to the CNAME"
},
"LoadBalancerParam": {
"Type": "String",
"Description": "Enter the loadbalancer name for the stack you want mapped to the CNAME"
}
},
"Resources" : {
"SubdomainDNSRecord" : {
"Type" : "AWS::Route53::RecordSet",
"Properties" : {
"HostedZoneName" : { "Fn::Join" : [ "", [{"Ref" : "HostedZone"}, "." ]]},
"Comment" : "CNAME redirect to subdomain.",
"Name" : { "Fn::Join" : [ "", [{"Ref" : "SubdomainParam"}, ".", {"Ref" : "HostedZone"}, "."]]},
"Type" : "CNAME",
"TTL" : "900",
"ResourceRecords" : [{
"Ref": "LoadBalancerParam"
}]
}
}
},
"Outputs" : {
"CNAME" : {
"Description" : "Fully qualified domain name",
"Value" : { "Ref" : "SubdomainDNSRecord" }
}
}
}
#!/usr/bin/env bash
aws cloudformation create-stack --profile default --stack-name stage-blog-cname \
--template-body file:///Users/claytongraham/data/github/dronze/dronze-cicd/cf/r53_cname.json \
--parameters ParameterKey=HostedZone,ParameterValue=dronze.com \
ParameterKey=SubdomainParam,ParameterValue=stage.blog \
ParameterKey=LoadBalancerParam,ParameterValue=dronze-elb-PROD-1699664721.us-west-2.elb.amazonaws.com
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "cloudformation:*",
"Effect": "Allow",
"Resource": "arn:aws:cloudformation:us-west-2:715212546939:stack/*"
},
{
"Action": "route53:*",
"Effect": "Allow",
"Resource": "arn:aws:route53:::hostedzone/Z3VRQF6A9GQX5I"
},
{
"Action": "codepipeline:*",
"Effect": "Allow",
"Resource": "*"
}
]
}