Skip to content

Commit

Permalink
Document api
Browse files Browse the repository at this point in the history
Signed-off-by: Tamal Saha <[email protected]>
  • Loading branch information
tamalsaha committed Aug 12, 2020
1 parent 9ed286e commit e6d5325
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 21 deletions.
71 changes: 65 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
# offline-license-server

AppsCode License server. We call it `offline` license server because once you have received the license file, no further connection is required with the license server. So, these licenses can be used within an air-gapped Kubernetes cluster.

## API Reference

### Cluster UID

We use the `uid` of the `kube-system` namespace as the Kubernetes cluster UID. Please run the command below to get the cluster uid for your cluster:

```console
kubectl get ns kube-system -o=jsonpath='{.metadata.uid}'
```

### License Issuer CA

The license issuer ca can be found here: https://licenses.appscode.com/certificates/ca.crt

### List of products

- kubedb-community
- kubedb-enterprise
- stash-community
- stash-enterprise

### Email Address Requirements

You must provide a valid non-disposable email to acquire license. For Enterprise products, you must provide a valid work email to acquire license.

### Register Email

Make the api call below with a valid email address. We are going to email you a token for the License server.

```console
curl -d "email=***" -X POST https://license-issuer.appscode.com/register
```

### Issue License

You can use the `{email, token}` to issue license using `curl` from command line. In the example below replace `***` with an actual token you have received in the email.

```console
# pass request body as application/x-www-form-urlencoded

curl -X POST \
-d "name=***&email=***&product=kubedb-community&cluster=***&tos=true&token=***" \
https://license-issuer.appscode.com/issue-license

# pass request body as application/json

curl -X POST -H "Content-Type: application/json" \
-d '{"name":"***","email":"***","product":"kubedb-community","cluster":"***","tos":"true","token":"***"}' \
https://license-issuer.appscode.com/issue-license

# pretty printed request json body
{
"name": "***",
"email": "***",
"product": "kubedb-community",
"cluster": "***",
"tos": "true",
"token": "***"
}
```

## Installation

These instructions are useful if you are trying to deploy your own license server or update an existing license server.

- Download pre-built binary into a server

```console
Expand Down Expand Up @@ -31,9 +96,3 @@ sudo systemctl enable offline-license-server.service
sudo systemctl start offline-license-server
sudo journalctl -f -u offline-license-server
```

## Verify Email

```
curl -d "[email protected]" -X POST http://localhost:4000/register
```
21 changes: 10 additions & 11 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ func (s *Server) HandleRegisterEmail(req RegisterRequest) error {
}

{
subject := "Token for AppsCode License server"
subject := "AppsCode license server token"
src := `Hi,
Please use the token below to issue licenses with this email.
Please use the token below to issue licenses using this email address.
{{.Token}}
Expand Down Expand Up @@ -315,16 +315,15 @@ AppsCode Team`
}
}

// mark email as verified
if exists, err := s.fs.Exists(context.TODO(), EmailVerifiedPath(domain, info.Email)); err == nil && !exists {
err = s.fs.WriteFile(context.TODO(), EmailVerifiedPath(domain, info.Email), []byte(timestamp))
if err != nil {
return err
}
}

{
if info.Token != "" {
// mark email as verified
if exists, err := s.fs.Exists(context.TODO(), EmailVerifiedPath(domain, info.Email)); err == nil && !exists {
err = s.fs.WriteFile(context.TODO(), EmailVerifiedPath(domain, info.Email), []byte(timestamp))
if err != nil {
return err
}
}
respond(ctx, crtLicense)
} else {
respond(ctx, []byte("Your license has been emailed!"))
Expand All @@ -337,7 +336,7 @@ AppsCode Team`
func (s *Server) GetDomainLicense(domain string, product string) (*ProductLicense, error) {
if !emailproviders.IsWorkEmail(domain) {
if IsEnterpriseProduct(product) {
return nil, apierrors.NewBadRequest("requires work email for enterprise license")
return nil, apierrors.NewBadRequest("Please provide work email to issue license for Enterprise products.")
}
ttl := metav1.Duration{Duration: DefaultTTLForCommunityProduct}
return &ProductLicense{
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type LicenseForm struct {
Name string `form:"name" binding:"Required" json:"name"`
Email string `form:"email" binding:"Required;Email" json:"email"`
Product string `form:"product" binding:"Required" json:"product"`
Cluster string `form:"cluster-uid" binding:"Required" json:"cluster"`
Cluster string `form:"cluster" binding:"Required" json:"cluster"`
Tos string `form:"tos" binding:"Required" json:"tos"`
Token string `form:"token" json:"token"`
}
Expand Down
4 changes: 2 additions & 2 deletions templates/bindata.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (fi bindataFileInfo) Sys() interface{} {
return nil
}

var _indexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x57\xcd\x72\xdc\x36\x0c\xbe\xf7\x29\x10\x5e\x72\xa9\x96\xc9\xad\xcd\x50\x9a\xb6\xb6\x0f\x99\x76\xda\x4c\x9d\x4b\x8f\x5c\x12\xbb\x62\x4c\x91\x1c\x02\xda\x78\xa7\xd3\x77\xef\x50\xd2\xae\xd7\x2b\xa5\xfe\x89\x33\x53\x1f\x6c\x41\xf8\xf9\x88\x8f\x00\x04\xab\x57\x97\x7f\x5c\x7c\xfc\xeb\xc3\x15\xb4\xdc\xf9\xe6\x3b\x35\xfe\x01\x50\x2d\x6a\x5b\x1e\x00\x54\x87\xac\xc1\xb4\x3a\x13\x72\x2d\x7a\xde\x54\x3f\x08\x90\xa7\xca\xa0\x3b\xac\xc5\xce\xe1\xe7\x14\x33\x0b\x30\x31\x30\x06\xae\xc5\x67\x67\xb9\xad\x2d\xee\x9c\xc1\x6a\x10\xbe\x07\x17\x1c\x3b\xed\x2b\x32\xda\x63\xfd\xf6\x2e\x14\x3b\xf6\xd8\xfc\x9c\x12\x5d\x44\x8b\xf0\x9b\x33\x18\x08\xe1\x1a\xf3\x0e\xb3\x92\xa3\x7a\x34\xf5\x2e\xdc\x0c\x4f\x00\x19\x7d\x2d\x88\xf7\x1e\xa9\x45\x64\x31\xbd\x6e\x33\x6e\x6a\xd1\x32\x27\x7a\x27\xa5\xb1\x61\xf5\x89\x2c\x7a\xb7\xcb\xab\x80\x2c\x43\xea\xe4\xba\xf7\x9d\xfe\xe9\xcd\xea\xc7\xd5\x1b\x69\x88\x46\x79\xd5\xb9\xb0\x32\x44\x63\x9c\xe1\x68\x4a\x1e\xc8\x50\xeb\x68\xf7\xd3\x11\x08\x0d\xbb\x18\xc0\x78\x4d\x54\x8b\x49\x14\xcd\x84\xaf\xac\xdb\x1d\x74\x85\x0e\xed\x02\xe6\xa3\xb6\x10\xfc\xf6\xa0\x1e\x12\x3b\x51\x01\x7c\x81\x83\x3b\x67\xd9\xbe\x3d\x09\xb5\x89\xb9\x03\x3d\xe0\xd7\x42\x3a\xa2\x1e\x2b\x3f\x7a\x0a\xe8\x90\xdb\x68\x6b\x91\x22\xf1\x3d\x90\xd3\x13\x6e\x1c\x7a\x7b\x4f\x5b\x48\xd6\x6b\xf4\x07\x8b\x41\x10\xcd\xef\xba\x43\x25\x07\xe1\xcc\xfa\x2c\xdf\x1c\xfd\x59\x3c\x00\xe5\x42\xea\xf9\xec\x25\x4c\xd5\x53\x7e\x8b\x99\x6e\x8a\x38\x38\xce\xb5\xbc\x4f\x58\x0b\xc6\xdb\x05\x5d\xf2\xda\x60\x1b\xbd\xc5\x5c\x8b\x73\xb5\x3c\x3b\xbc\xb4\x6e\x77\x8f\x9b\xd9\x8b\xe7\x90\x75\xd5\x69\xe7\x1f\xcb\x16\xb4\x9a\x2a\x67\x62\xa0\xca\xe3\x86\x4f\xc4\xec\xb6\x2d\x3f\x8d\x4c\x2c\xc8\xcf\x63\xf3\x0b\xae\xff\x49\x27\xc0\x4e\xfb\x1e\x1f\xe4\xb9\xb4\x4d\xd2\xc7\x9e\x29\xe9\x81\xa3\x8a\x3a\xed\x7d\x79\x28\x89\xcf\x12\x2d\xa9\x1e\xa9\xd7\x04\x1b\x5d\x61\xd8\xa1\x8f\x09\x45\xa3\xa4\x9b\x41\xc8\x82\xf1\x34\xe0\x65\x8a\x97\x90\x6f\x8d\xd7\x9d\x2e\xad\x56\x71\x76\x3a\x6c\xfd\xe3\x4f\x31\xab\x2a\x00\xf5\xaa\xaa\x40\xa5\x03\x4a\x8b\x3e\x95\xf3\x58\x1d\xb6\x65\x5c\x7c\x6c\x1d\xc1\x70\x23\xe0\x08\x5c\xd8\x69\xef\xac\x92\xa9\x81\xaa\x7a\xf9\x7a\xfd\x90\xa3\xed\x0d\x3f\xbf\xbf\x4f\x6c\x08\x3d\x9a\x45\x4a\x47\x0d\xb8\x32\x93\x46\x40\x31\x55\xed\x41\x9c\x3b\x01\xa8\x98\x86\x71\x3b\x15\xda\x4d\xbf\x46\xbb\xae\x4c\xec\xba\x3e\x38\xde\xcf\x2b\xb2\xfc\x34\xbf\xf6\x6b\xbc\xfc\x05\x2e\x0e\x66\x70\x65\x5d\x09\xa3\xe4\x18\x6e\xc1\xeb\xf1\xe0\x18\x18\x73\xca\x8e\x16\xe6\xd6\x29\xfa\xd5\xd1\xee\x65\xe0\x89\x35\xb5\x0f\xa6\x7e\x5d\xac\x5e\x3a\xf3\x11\xfa\xc1\xc4\x47\xec\xaf\xcc\x5b\xc9\xb1\x52\xe6\x9d\x35\xef\xa2\x6f\x33\xbf\xcb\xfd\xe5\x80\x8c\x04\x17\xbe\x27\xc6\x0c\xef\x2f\xbf\xcd\xd7\xcf\x8c\xf1\xab\xde\xd9\xff\xcd\x47\x10\x16\x06\x93\x0b\x9b\x28\x9a\x3f\xfb\x00\xa5\xfe\x74\xb0\xef\x40\x99\x68\xb1\x29\x3d\x61\xd8\xc3\x16\x19\x02\x41\x11\x2b\xda\x13\x63\x07\x55\xac\x3f\x51\x0c\x49\x73\x5b\xbf\xfe\x7b\x55\x36\x46\xab\x59\xaf\x7a\x67\xff\x79\xad\xe4\xe0\x5e\x66\xda\x57\xdd\xdf\x63\x2e\xe0\xde\x1d\x9b\x16\xcd\xcd\x3a\xde\x2e\x4e\xfd\xc2\xf4\x74\x33\x1c\x49\x4c\x1c\x1f\x5d\x0e\xed\xc0\xb9\x47\x31\xff\xc8\x01\xbc\x07\xbd\xcd\x88\xc0\x11\xb8\xc5\x39\x80\x3e\xdb\x4f\x75\x4a\x54\x78\x58\x99\xd8\x49\x8f\x5b\xed\x25\x47\x92\x4b\xed\xd5\x30\xe6\x8e\x40\x07\x5b\xd6\xec\xb1\xaf\x48\x49\x3d\x33\x9d\xf7\xcd\x52\xe1\x3e\xbd\x73\x4a\x19\x6c\x73\xec\x13\x3e\xeb\x12\xd6\x3d\xf3\xdd\xda\x3c\x49\xe5\xdb\xef\xc2\x8d\x68\xae\xfb\x75\xe7\x58\xc9\xf1\xfd\xd3\xce\xaa\x64\x59\x84\x8f\x0b\xf8\x9d\xb2\x4c\x92\x61\x3b\x1e\xb7\xf9\x71\x89\x57\x72\xfc\x5f\xe7\xdf\x00\x00\x00\xff\xff\x87\x5e\xe1\x70\x03\x0d\x00\x00")
var _indexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x57\xcd\x72\xdc\x36\x0c\xbe\xf7\x29\x10\x5e\x72\xa9\x96\xc9\xad\xcd\x50\x9a\xb6\xb6\x0f\x99\x76\xda\x4c\x9d\x4b\x8f\x5c\x12\xbb\x62\x4c\x91\x1c\x02\xda\x78\xa7\xd3\x77\xef\x50\xd2\xae\xd7\x2b\xa5\xfe\x89\x33\x53\x1f\x6c\x41\xf8\xf9\x88\x8f\x00\x04\xab\x57\x97\x7f\x5c\x7c\xfc\xeb\xc3\x15\xb4\xdc\xf9\xe6\x3b\x35\xfe\x01\x50\x2d\x6a\x5b\x1e\x00\x54\x87\xac\xc1\xb4\x3a\x13\x72\x2d\x7a\xde\x54\x3f\x08\x90\xa7\xca\xa0\x3b\xac\xc5\xce\xe1\xe7\x14\x33\x0b\x30\x31\x30\x06\xae\xc5\x67\x67\xb9\xad\x2d\xee\x9c\xc1\x6a\x10\xbe\x07\x17\x1c\x3b\xed\x2b\x32\xda\x63\xfd\xf6\x2e\x14\x3b\xf6\xd8\xfc\x9c\x12\x5d\x44\x8b\xf0\x9b\x33\x18\x08\xe1\x1a\xf3\x0e\xb3\x92\xa3\x7a\x34\xf5\x2e\xdc\x0c\x4f\x00\x19\x7d\x2d\x88\xf7\x1e\xa9\x45\x64\x31\xbd\x6e\x33\x6e\x6a\xd1\x32\x27\x7a\x27\xa5\xb1\x61\xf5\x89\x2c\x7a\xb7\xcb\xab\x80\x2c\x43\xea\xe4\xba\xf7\x9d\xfe\xe9\xcd\xea\xc7\xd5\x1b\x69\x88\x46\x79\xd5\xb9\xb0\x32\x44\x63\x9c\xe1\x68\x4a\x1e\xc8\x50\xeb\x68\xf7\xd3\x11\x08\x0d\xbb\x18\xc0\x78\x4d\x54\x8b\x49\x14\xcd\x84\xaf\xac\xdb\x1d\x74\x85\x0e\xed\x02\xe6\xa3\xb6\x10\xfc\xf6\xa0\x1e\x12\x3b\x51\x01\x7c\x81\x83\x3b\x67\xd9\xbe\x3d\x09\xb5\x89\xb9\x03\x3d\xe0\xd7\x42\x3a\xa2\x1e\x2b\x3f\x7a\x0a\xe8\x90\xdb\x68\x6b\x91\x22\xf1\x3d\x90\xd3\x13\x6e\x1c\x7a\x7b\x4f\x5b\x48\xd6\x6b\xf4\x07\x8b\x41\x10\xcd\xef\xba\x43\x25\x07\xe1\xcc\xfa\x2c\xdf\x1c\xfd\x59\x3c\x00\xe5\x42\xea\xf9\xec\x25\x4c\xd5\x53\x7e\x8b\x99\x6e\x8a\x38\x38\xce\xb5\xbc\x4f\x58\x0b\xc6\xdb\x05\x5d\xf2\xda\x60\x1b\xbd\xc5\x5c\x8b\x73\xb5\x3c\x3b\xbc\xb4\x6e\x77\x8f\x9b\xd9\x8b\xe7\x90\x75\xd5\x69\xe7\x1f\xcb\x16\xb4\x9a\x2a\x67\x62\xa0\xca\xe3\x86\x4f\xc4\xec\xb6\x2d\x3f\x8d\x4c\x2c\xc8\xcf\x63\xf3\x0b\xae\xff\x49\x27\xc0\x4e\xfb\x1e\x1f\xe4\xb9\xb4\x4d\xd2\xc7\x9e\x29\xe9\x81\xa3\x8a\x3a\xed\x7d\x79\x28\x89\xcf\x12\x2d\xa9\x1e\xa9\xd7\x04\x1b\x5d\x61\xd8\xa1\x8f\x09\x45\xa3\xa4\x9b\x41\xc8\x82\xf1\x34\xe0\x65\x8a\x97\x90\x6f\x8d\xd7\x9d\x2e\xad\x56\x71\x76\x3a\x6c\xfd\xe3\x4f\x31\xab\x2a\x00\xf5\xaa\xaa\x40\xa5\x03\x4a\x8b\x3e\x95\xf3\x58\x1d\xb6\x65\x5c\x7c\x6c\x1d\xc1\x70\x23\xe0\x08\x5c\xd8\x69\xef\xac\x92\xa9\x81\xaa\x7a\xf9\x7a\xfd\x90\xa3\xed\x0d\x3f\xbf\xbf\x4f\x6c\x08\x3d\x9a\x45\x4a\x47\x0d\xb8\x32\x93\x46\x40\x31\x55\xed\x41\x9c\x3b\x01\xa8\x98\x86\x71\x3b\x15\xda\x4d\xbf\x46\xbb\xae\x4c\xec\xba\x3e\x38\xde\xcf\x2b\xb2\xfc\x34\xbf\xf6\x6b\xbc\xfc\x05\x2e\x0e\x66\x70\x65\x5d\x09\xa3\xe4\x18\x6e\xc1\xeb\xf1\xe0\x18\x18\x73\xca\x8e\x16\xe6\xd6\x29\xfa\xd5\xd1\xee\x65\xe0\x89\x35\xb5\x0f\xa6\x7e\x5d\xac\x5e\x3a\xf3\x11\xfa\xc1\xc4\x47\xec\xaf\xcc\x5b\xc9\xb1\x52\xe6\x9d\x35\xef\xa2\x6f\x33\xbf\xcb\xfd\xe5\x80\x8c\x04\x17\xbe\x27\xc6\x0c\xef\x2f\xbf\xcd\xd7\xcf\x8c\xf1\xff\x37\x1f\x40\x58\x18\x4a\x2e\x6c\xa2\x68\xfe\xec\x03\x94\xda\xd3\xc1\xbe\x03\x65\xa2\xc5\xa6\xf4\x83\x61\x0f\x5b\x64\x08\x04\x45\xac\x68\x4f\x8c\x1d\x54\xb1\xfe\x44\x31\x24\xcd\x6d\xfd\xfa\xef\x55\xd9\x16\xad\x66\xbd\xea\x9d\xfd\xe7\xb5\x92\x83\x7b\x99\x67\x5f\x75\x77\x8f\x21\xff\xde\xfd\x9a\x16\xcd\xcd\x3a\xde\x2e\x4e\xfc\xc2\xf4\x74\x2b\x1c\x49\x4c\x1c\x1f\x5d\x0e\xad\xc0\xb9\x47\x31\xff\xc0\x01\xbc\x07\xbd\xcd\x88\xc0\x11\xb8\xc5\x39\x80\x3e\xdb\x4d\x75\x4a\x54\x78\x58\x99\xd8\x49\x8f\x5b\xed\x25\x47\x92\x4b\xad\xd5\x30\xe6\x8e\x40\x07\x5b\x56\xec\xb1\xa7\x48\x49\x3d\x33\x9d\xf7\xcc\x52\xd1\x3e\xbd\x6b\x4a\x19\x6c\x73\xec\x13\x3e\xeb\x12\xd6\x3d\xf3\xdd\xca\x3c\x49\xe5\xbb\xef\xc2\x8d\x68\xae\xfb\x75\xe7\x58\xc9\xf1\xfd\xd3\xce\xaa\x64\x59\x82\x8f\xcb\xf7\x9d\xb2\x4c\x91\x61\x33\x1e\x37\xf9\x71\x81\x57\x72\xfc\x3f\xe7\xdf\x00\x00\x00\xff\xff\x4c\xb1\xe6\xed\xff\x0c\x00\x00")

func indexHtmlBytes() ([]byte, error) {
return bindataRead(
Expand All @@ -92,7 +92,7 @@ func indexHtml() (*asset, error) {
return nil, err
}

info := bindataFileInfo{name: "index.html", size: 3331, mode: os.FileMode(420), modTime: time.Unix(1573722179, 0)}
info := bindataFileInfo{name: "index.html", size: 3327, mode: os.FileMode(420), modTime: time.Unix(1573722179, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
Expand Down
2 changes: 1 addition & 1 deletion templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ <h1 class="title">
<label class="label">Kubernetes Cluster ID</label>
<div class="control">
<input
name="cluster-uid"
name="cluster"
class="input"
type="text"
placeholder=""
Expand Down

0 comments on commit e6d5325

Please sign in to comment.