From adf989474934cb46c1219d74d1ec99cc2434b83f Mon Sep 17 00:00:00 2001
From: Tamal Saha
Date: Sun, 17 Mar 2024 09:13:52 -0700
Subject: [PATCH] Add coupon code support
Signed-off-by: Tamal Saha
---
.github/workflows/ci.yml | 4 +-
Makefile | 2 +-
README.md | 4 +-
go.mod | 4 +-
go.sum | 8 +-
main_extras.go | 2 +-
pkg/server/coupon.go | 34 +
pkg/server/enterprise.go | 2 +-
pkg/server/options.go | 5 +
pkg/server/server.go | 37 +-
pkg/server/types.go | 1 +
templates/index.html | 6 +
.../golang/protobuf/jsonpb/decode.go | 1 +
.../golang/protobuf/jsonpb/encode.go | 1 +
.../github.com/golang/protobuf/ptypes/any.go | 7 +-
.../encoding/protojson/well_known_types.go | 4 +
.../internal/editiondefaults/defaults.go | 12 +
.../editiondefaults}/editions_defaults.binpb | 2 +-
.../protobuf/internal/encoding/json/decode.go | 2 +-
.../protobuf/internal/filedesc/desc.go | 67 +-
.../protobuf/internal/filedesc/desc_init.go | 52 +
.../protobuf/internal/filedesc/desc_lazy.go | 28 +
.../protobuf/internal/filedesc/editions.go | 142 ++
.../protobuf/internal/genid/descriptor_gen.go | 152 +-
.../internal/genid/go_features_gen.go | 31 +
.../protobuf/internal/genid/struct_gen.go | 5 +
.../protobuf/internal/genid/type_gen.go | 38 +
.../protobuf/internal/impl/codec_extension.go | 22 +-
.../protobuf/internal/impl/codec_tables.go | 2 +-
.../internal/impl/message_reflect_field.go | 2 +-
.../protobuf/internal/strs/strings.go | 2 +-
.../protobuf/internal/version/version.go | 2 +-
.../protobuf/reflect/protodesc/desc_init.go | 42 +-
.../reflect/protodesc/desc_resolve.go | 4 +-
.../reflect/protodesc/desc_validate.go | 6 +-
.../protobuf/reflect/protodesc/editions.go | 131 +-
.../protobuf/reflect/protoreflect/proto.go | 2 +
.../reflect/protoreflect/source_gen.go | 2 -
.../types/descriptorpb/descriptor.pb.go | 1254 ++++++++---------
.../types/gofeaturespb/go_features.pb.go | 177 +++
.../types/gofeaturespb/go_features.proto | 28 +
vendor/modules.txt | 8 +-
42 files changed, 1544 insertions(+), 793 deletions(-)
create mode 100644 pkg/server/coupon.go
create mode 100644 vendor/google.golang.org/protobuf/internal/editiondefaults/defaults.go
rename vendor/google.golang.org/protobuf/{reflect/protodesc => internal/editiondefaults}/editions_defaults.binpb (69%)
create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/editions.go
create mode 100644 vendor/google.golang.org/protobuf/internal/genid/go_features_gen.go
create mode 100644 vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go
create mode 100644 vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.proto
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6651f6c7..4ed202c0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,10 +18,10 @@ jobs:
name: Build
runs-on: ubuntu-20.04
steps:
- - name: Set up Go 1.21
+ - name: Set up Go 1.22
uses: actions/setup-go@v1
with:
- go-version: '1.21'
+ go-version: '1.22'
id: go
- name: Check out code into the Go module directory
diff --git a/Makefile b/Makefile
index cefaaede..efa79978 100644
--- a/Makefile
+++ b/Makefile
@@ -53,7 +53,7 @@ BIN_PLATFORMS := $(DOCKER_PLATFORMS) darwin/amd64 darwin/arm64
OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS))
ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH))
-GO_VERSION ?= 1.21
+GO_VERSION ?= 1.22
BUILD_IMAGE ?= ghcr.io/appscode/golang-dev:$(GO_VERSION)
OUTBIN = bin/$(BIN)-$(OS)-$(ARCH)
diff --git a/README.md b/README.md
index d569db6f..2f50173f 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,7 @@ These instructions are useful if you are trying to deploy your own license serve
- Download pre-built binary into a server
```bash
-curl -fsSL -O https://github.com/bytebuilders/offline-license-server/releases/download/v0.0.59/offline-license-server-linux-amd64
+curl -fsSL -O https://github.com/bytebuilders/offline-license-server/releases/download/v0.0.61/offline-license-server-linux-amd64
chmod +x offline-license-server-linux-amd64
mv offline-license-server-linux-amd64 /usr/local/bin/offline-license-server
sudo systemctl restart offline-license-server
@@ -86,7 +86,7 @@ sudo systemctl restart offline-license-server
- Install systemd service
```bash
-curl -fsSL -O https://github.com/bytebuilders/offline-license-server/raw/v0.0.59/hack/systemd/offline-license-server.service
+curl -fsSL -O https://github.com/bytebuilders/offline-license-server/raw/v0.0.61/hack/systemd/offline-license-server.service
chmod +x offline-license-server.service
# 1. Copy Google cloud service account json key to /root/app/gcloud.json
diff --git a/go.mod b/go.mod
index ec37b37a..df05aa1b 100644
--- a/go.mod
+++ b/go.mod
@@ -69,7 +69,7 @@ require (
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/protobuf v1.5.3 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
@@ -114,7 +114,7 @@ require (
google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240205150955-31a09d347014 // indirect
google.golang.org/grpc v1.61.0 // indirect
- google.golang.org/protobuf v1.32.0 // indirect
+ google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.66.6 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/go.sum b/go.sum
index 19d79d88..7a394e4e 100644
--- a/go.sum
+++ b/go.sum
@@ -182,8 +182,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -713,8 +713,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
-google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
diff --git a/main_extras.go b/main_extras.go
index 0f119b11..5fd7c9f2 100644
--- a/main_extras.go
+++ b/main_extras.go
@@ -88,7 +88,7 @@ func main_sheets() {
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
- err = server.LogLicense(si, &info)
+ err = server.LogLicense(si, &info, "")
if err != nil {
klog.Fatal(err)
}
diff --git a/pkg/server/coupon.go b/pkg/server/coupon.go
new file mode 100644
index 00000000..6ef73924
--- /dev/null
+++ b/pkg/server/coupon.go
@@ -0,0 +1,34 @@
+/*
+Copyright AppsCode Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package server
+
+import "strings"
+
+func ParseCouponCodes(in string) map[string]string {
+ parts := strings.FieldsFunc(in, func(r rune) bool {
+ return r == ',' || r == ';'
+ })
+
+ couponCodes := map[string]string{}
+ for _, part := range parts {
+ if event, code, ok := strings.Cut(part, ":"); ok {
+ couponCodes[code] = event
+ }
+ }
+
+ return couponCodes
+}
diff --git a/pkg/server/enterprise.go b/pkg/server/enterprise.go
index e3f8c153..0d7cb276 100644
--- a/pkg/server/enterprise.go
+++ b/pkg/server/enterprise.go
@@ -29,7 +29,7 @@ func (s *Server) IssueEnterpriseLicense(info LicenseForm, extendBy time.Duration
}
{
- err = LogLicense(s.sheet, accesslog)
+ err = LogLicense(s.sheet, accesslog, "")
if err != nil {
return err
}
diff --git a/pkg/server/options.go b/pkg/server/options.go
index d598068d..b7167031 100644
--- a/pkg/server/options.go
+++ b/pkg/server/options.go
@@ -53,6 +53,8 @@ type Options struct {
BlockedEmails []string
EnableDripCampaign bool
+
+ Coupons string
}
func NewOptions() *Options {
@@ -75,6 +77,7 @@ func NewOptions() *Options {
listmonkPassword: os.Getenv("LISTMONK_PASSWORD"),
GoogleCredentialDir: cwd,
EnableDripCampaign: true,
+ Coupons: os.Getenv("COUPONS"),
}
}
@@ -108,4 +111,6 @@ func (s *Options) AddFlags(fs *pflag.FlagSet) {
fs.StringSliceVar(&s.BlockedEmails, "blocked-emails", s.BlockedEmails, "Emails blocked from downloading license automatically")
fs.BoolVar(&s.EnableDripCampaign, "drip-campaign", s.EnableDripCampaign, "Set true to enable drip campaign runner")
+
+ fs.StringVar(&s.Coupons, "coupons", s.Coupons, "Coupon codes")
}
diff --git a/pkg/server/server.go b/pkg/server/server.go
index 9bfe605a..1e7e7b15 100644
--- a/pkg/server/server.go
+++ b/pkg/server/server.go
@@ -85,6 +85,8 @@ type Server struct {
blockedDomains sets.String
blockedEmails sets.String
+
+ couponCodes map[string]string
}
func New(opts *Options) (*Server, error) {
@@ -171,6 +173,7 @@ func New(opts *Options) (*Server, error) {
zoomAccountEmail: os.Getenv("ZOOM_ACCOUNT_EMAIL"),
blockedDomains: sets.NewString(opts.BlockedDomains...),
blockedEmails: sets.NewString(opts.BlockedEmails...),
+ couponCodes: ParseCouponCodes(opts.Coupons),
}, nil
}
@@ -432,7 +435,7 @@ func (s *Server) HandleIssueLicense(ctx *macaron.Context, info LicenseForm) erro
if err != nil {
return err
}
- err = s.recordLicenseEvent(ctx, info, timestamp, EventTypeLicenseBlocked)
+ err = s.recordLicenseEvent(ctx, info, timestamp, "", EventTypeLicenseBlocked)
if err != nil {
return err
}
@@ -456,6 +459,11 @@ func (s *Server) HandleIssueLicense(ctx *macaron.Context, info LicenseForm) erro
if err != nil {
return err
}
+ couponEvent, couponOK := s.couponCodes[info.Coupon]
+ if couponOK {
+ oneyr := metav1.Duration{Duration: DefaultTTLForCommunityProduct}
+ license.TTL = &oneyr
+ }
crtLicense, err := s.CreateOrRetrieveLicense(info, *license, info.Cluster)
if err != nil {
return err
@@ -525,7 +533,7 @@ func (s *Server) HandleIssueLicense(ctx *macaron.Context, info LicenseForm) erro
// return err
//}
- err = s.recordLicenseEvent(ctx, info, timestamp, EventTypeLicenseIssued)
+ err = s.recordLicenseEvent(ctx, info, timestamp, couponEvent, EventTypeLicenseIssued)
return
}()
}
@@ -565,7 +573,7 @@ func (s *Server) HandleIssueLicense(ctx *macaron.Context, info LicenseForm) erro
return nil
}
-func (s *Server) recordLicenseEvent(ctx *macaron.Context, info LicenseForm, timestamp string, event LicenseEventType) error {
+func (s *Server) recordLicenseEvent(ctx *macaron.Context, info LicenseForm, timestamp, couponEvent string, event LicenseEventType) error {
domain := Domain(info.Email)
// record request
@@ -594,7 +602,7 @@ func (s *Server) recordLicenseEvent(ctx *macaron.Context, info LicenseForm, time
return err
}
- err = LogLicense(s.sheet, &accesslog)
+ err = LogLicense(s.sheet, &accesslog, couponEvent)
if err != nil {
return err
}
@@ -679,12 +687,29 @@ func (s *Server) CreateOrRetrieveLicense(info LicenseForm, license ProductLicens
return CreateLicense(s.fs, s.certs, info, license, cluster, nil)
}
-func LogLicense(si *gdrive.Spreadsheet, info *LogEntry) error {
+func LogLicense(si *gdrive.Spreadsheet, info *LogEntry, couponEvent string) error {
const sheetName = "License Issue Log"
sheetId, err := si.EnsureSheet(sheetName, LogEntry{}.Headers())
if err != nil {
return err
}
- return si.AppendRowData(sheetId, info.Data(), false)
+ err = si.AppendRowData(sheetId, info.Data(), false)
+ if err != nil {
+ return err
+ }
+
+ if couponEvent != "" {
+ couponSheet := "COUPON_" + couponEvent
+ couponSheetId, err := si.EnsureSheet(couponSheet, LogEntry{}.Headers())
+ if err != nil {
+ return err
+ }
+ err = si.AppendRowData(couponSheetId, info.Data(), false)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
}
diff --git a/pkg/server/types.go b/pkg/server/types.go
index ce96dd99..9e38ca97 100644
--- a/pkg/server/types.go
+++ b/pkg/server/types.go
@@ -50,6 +50,7 @@ type LicenseForm struct {
Cluster string `form:"cluster" binding:"Required" json:"cluster"`
Tos string `form:"tos" binding:"Required" json:"tos"`
Token string `form:"token" json:"token"`
+ Coupon string `form:"coupon" json:"coupon"`
}
type LicenseMailData struct {
diff --git a/templates/index.html b/templates/index.html
index 8350c721..c496d8f8 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -91,6 +91,12 @@ AppsCode License Server
>
+