Skip to content

maruina/go-infrabin

Repository files navigation

go-infrabin

Go Report Card Coverage Status

infrabin written in go.

Warning: go-infrabin exposes sensitive endpoints and should NEVER be used on the public Internet.

Usage

go-infrabin exposes three ports:

  • 8888 as a http rest port
  • 8887 as http Prometheus port
  • 50051 as a grpc port

Installation

See the README.

Command line flags

  • --aws-metadata-endpoint: AWS Metadata Endpoint (default http://169.254.169.254/latest/meta-data/)
  • --drain-timeout: Drain timeout (default 15s)
  • --enable-proxy-endpoint: When enabled allows /proxy and /aws endpoints
  • --proxy-allow-regexp: Regular expression to allow URL called by the /proxy endpoint (default ".*")
  • --intermittent-errors: Number of consecutive 503 errors before returning 200 when calling the /intermittent endpoint (default 2)
  • --grpc-host: gRPC host (default 0.0.0.0)
  • --grpc-port: gRPC port (default 50051)
  • -h, --help: Help for go-infrabin
  • --http-idle-timeout: HTTP idle timeout (default 15s)
  • --http-read-header-timeout: HTTP read header timeout (default 15s)
  • --http-read-timeout: HTTP read timeout (default 1m0s)
  • --http-write-timeout: HTTP write timeout (default 2m1s)
  • --max-delay duration: Maximum delay (default 2m0s)
  • --prom-host: Prometheus metrics host (default 0.0.0.0)
  • --prom-port: Prometheus metrics port (default 8887)
  • --server-host: HTTP server host (default 0.0.0.0)
  • --server-port: HTTP server port (default 8888)

Environment variables

  • INFRABIN_MAX_DELAY: to change the maximum value for the /delay endpoint. Default to 120.
  • FAIL_ROOT_HANDLER: if set, the / endpoint will return a 503. This is useful when doing a B/G deployment to test the failure and rollback scenario.

Service Endpoints

  • grpc: infrabin.Infrabin.Root rest: GET /

    • grpc request
    message Empty {}
    
    • returns: a JSON response
    {
        "hostname": "<hostname>",
        "kubernetes": {
            "pod_name": "<pod_name>",
            "namespace": "<namespace>",
            "pod_ip": "<pod_ip>",
            "node_name": "<node_name>"
        }
    }
  • grpc: infrabin.Infrabin.Delay rest: GET /delay/<seconds>

    • grpc request
    message DelayRequest {
      int32 duration = 1;
    }
    
    • returns: a JSON response
    {
        "delay": "<seconds>"
    }
  • grpc: infrabin.Infrabin.Headers rest: GET /headers

    • grpc request
    message HeadersRequest {
        map<string, string> headers = 1;
    }
    
    {
        "headers": "<request headers>"
    }
  • grpc: infrabin.Infrabin.Env rest: GET /env/<env_var>

    • grpc request
    message EnvRequest {
        string env_var = 1;
    }
    
    • returns: a JSON response with the requested <env_var> or 404 if the environment variable does not exist
    {
        "env": {
            "<env_var>": "<env_var_value>"
        }
    }
  • grpc: infrabin.Infrabin.Proxy rest: GET /proxy

    • NOTE: --enable-proxy-endpoint must be set
    • NOTE: the target endpoint MUST provide a JSON response
    • grpc request
    message ProxyRequest {
        string method = 1;
        string url = 2;
        google.protobuf.Struct body = 3;
        map<string, string> headers = 4;
    }
    
    • returns: JSON of proxied request
  • grpc: infrabin.Infrabin.AWSMetadata rest: GET /aws/metadata/<path>

    • NOTE: --enable-proxy-endpoint must be set
    • grpc request
    message AWSRequest {
        string path = 1;
    }
    
    • returns: JSON of AWS GET call
  • grpc: infrabin.Infrabin.Any rest: GET /any/<path>

    message Any {
        string path = 1;
    }
    
    • returns: JSON of the requested path
  • grpc: infrabin.Infrabin.AWSAssume rest: GET /aws/assume/<role>

    • grpc request
    message AWSAssume {
        string role = 1;
    }
    
    • returns: JSON with the AssumedRoleId from AWS
    {
      "assumedRoleId":"AROAITQZVNCXXXXXXXXXX:aws-assume-session-go-infrabin"
    }
  • grpc: infrabin.Infrabin.AWSGetCallerIdentity rest: GET /aws/get-caller-identity

    • grpc request
    message Empty {}
    
    • returns: JSON with the GetCallerIdentity output from AWS
    {
      "getCallerIdentity": {
        "account": "123456789",
        "arn": "arn:aws:sts::1234546789:assumed-role/foo/bar",
        "user_id": "AROAITQZVNCVSVXXXXXX:foo"
      }
    }
  • grpc: infrabin.Infrabin.Intermittent rest: GET /intermittent

    • grpc request
    message Empty {}
    
    • returns: JSON with the remaining errors and then the configured --intermittent-errors flag
    {"code":14, "message":"2 errors left"}
    {"intermittent":{"consecutive_errors":2}

Errors

When calling the http endpoint, errors are mapped by grpc-gateway. They have the following format:

  • returns:
{
    "code": 3,
    "message": "type mismatch, parameter: duration, error: strconv.ParseInt: parsing \"21asd\": invalid syntax"
}

Contributing

To build locally, ensure you have compiled the protocol schemas. You will need the protoc binary which can install by following these instructions or if using Homebrew

brew install protobuf

You will also need to protoc go plugins for protofuf, grpc, and grpc-gateway. go mod tidy will fetch the versions specified in go.mod, and go install will install that version.

go get -t -v -d ./...
go install \
  github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
  github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
  google.golang.org/protobuf/cmd/protoc-gen-go \
  google.golang.org/grpc/cmd/protoc-gen-go-grpc

make run will compile the protocol buffers, or you can run:

make protoc

To run the tests:

make test

To run the server locally:

make run

To test http:

http localhost:8888/

To test grpc, use your favourite grpc tool like evans:

echo '{}' | evans -r cli call infrabin.Infrabin.Root