Skip to content

Commit ad185c4

Browse files
committed
Fix license expiration check
Signed-off-by: Tamal Saha <tamal@appscode.com>
1 parent e93a886 commit ad185c4

File tree

5 files changed

+73
-17
lines changed

5 files changed

+73
-17
lines changed

pkg/controllers/secret/license_syncer.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ import (
2020
"context"
2121
"crypto/x509"
2222
"fmt"
23+
"time"
2324

2425
"go.bytebuilders.dev/license-proxyserver/pkg/common"
2526
"go.bytebuilders.dev/license-proxyserver/pkg/storage"
2627
verifier "go.bytebuilders.dev/license-verifier"
2728

2829
core "k8s.io/api/core/v1"
2930
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31+
"k8s.io/klog/v2"
3032
kutil "kmodules.xyz/client-go"
3133
cu "kmodules.xyz/client-go/client"
3234
ctrl "sigs.k8s.io/controller-runtime"
@@ -100,6 +102,16 @@ func (r *LicenseSyncer) addLicense(data []byte) error {
100102
if err != nil {
101103
return err
102104
}
103-
r.R.Add(&license, nil)
105+
106+
if time.Until(license.NotAfter.Time) >= storage.MinRemainingLife {
107+
klog.InfoS("adding license",
108+
"id", license.ID,
109+
"product", license.ProductLine,
110+
"plan", license.PlanName,
111+
"tier", license.TierName,
112+
"expiry", license.NotAfter.UTC().Format(time.RFC822),
113+
)
114+
r.R.Add(&license, nil)
115+
}
104116
return nil
105117
}

pkg/manager/license_acquirer.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"path/filepath"
2626
"strings"
2727
"sync"
28+
"time"
2829

2930
"go.bytebuilders.dev/license-proxyserver/pkg/common"
3031
"go.bytebuilders.dev/license-proxyserver/pkg/storage"
@@ -88,10 +89,7 @@ func (r *LicenseAcquirer) Reconcile(ctx context.Context, request reconcile.Reque
8889
}
8990
}
9091
if cid != "" && len(features) > 0 {
91-
err = r.reconcile(ctx, managedCluster.Name, cid, features)
92-
if err != nil {
93-
return reconcile.Result{}, err
94-
}
92+
return r.reconcile(ctx, managedCluster.Name, cid, features)
9593
}
9694

9795
return reconcile.Result{}, nil
@@ -116,7 +114,7 @@ func (r *LicenseAcquirer) getLicenseRegistry(cid string) (*storage.LicenseRegist
116114
return reg, nil
117115
}
118116

119-
func (r *LicenseAcquirer) reconcile(ctx context.Context, clusterName, cid string, features []string) error {
117+
func (r *LicenseAcquirer) reconcile(ctx context.Context, clusterName, cid string, features []string) (reconcile.Result, error) {
120118
sec := core.Secret{
121119
ObjectMeta: metav1.ObjectMeta{
122120
Name: common.LicenseSecret,
@@ -130,14 +128,15 @@ func (r *LicenseAcquirer) reconcile(ctx context.Context, clusterName, cid string
130128
} else if apierrors.IsNotFound(err) {
131129
sec.Data = map[string][]byte{}
132130
} else {
133-
return err
131+
return reconcile.Result{}, err
134132
}
135133

136134
var errList []error
135+
var earliestExpired time.Time
137136

138137
reg, err := r.getLicenseRegistry(cid)
139138
if err != nil {
140-
return err
139+
return reconcile.Result{}, err
141140
}
142141
for _, feature := range features {
143142
l, found := reg.LicenseForFeature(feature)
@@ -156,6 +155,9 @@ func (r *LicenseAcquirer) reconcile(ctx context.Context, clusterName, cid string
156155
}
157156
if l != nil && l.Status == v1alpha1.LicenseActive {
158157
sec.Data[l.PlanName] = l.Data
158+
if earliestExpired.IsZero() || earliestExpired.After(l.NotAfter.Time) {
159+
earliestExpired = l.NotAfter.Time
160+
}
159161
}
160162
}
161163

@@ -165,12 +167,15 @@ func (r *LicenseAcquirer) reconcile(ctx context.Context, clusterName, cid string
165167
errList = append(errList, r.Create(context.TODO(), &sec))
166168
}
167169

168-
return utilerrors.NewAggregate(errList)
170+
if !earliestExpired.IsZero() {
171+
return reconcile.Result{
172+
RequeueAfter: time.Until(earliestExpired.Add(-storage.LicenseAcquisitionBuffer)),
173+
}, utilerrors.NewAggregate(errList)
174+
}
175+
return reconcile.Result{}, utilerrors.NewAggregate(errList)
169176
}
170177

171178
func (r *LicenseAcquirer) getNewLicense(ctx context.Context, cid string, features []string) (*v1alpha1.License, *v1alpha1.Contract, error) {
172-
logger := log.FromContext(ctx)
173-
174179
lc, err := pc.NewClient(r.BaseURL, r.Token, cid, r.CaCert, r.InsecureSkipTLSVerify, fmt.Sprintf("license-proxyserver-manager/%s", v.Version.Version))
175180
if err != nil {
176181
return nil, nil, err
@@ -180,7 +185,6 @@ func (r *LicenseAcquirer) getNewLicense(ctx context.Context, cid string, feature
180185
if err != nil {
181186
return nil, nil, err
182187
}
183-
logger.Info("acquired new license", "cid", cid, "features", strings.Join(features, ","))
184188

185189
caData, err := info.LoadLicenseCA()
186190
if err != nil {
@@ -200,5 +204,13 @@ func (r *LicenseAcquirer) getNewLicense(ctx context.Context, cid string, feature
200204
return nil, nil, err
201205
}
202206

207+
klog.InfoS("acquired new license",
208+
"cluster", cid,
209+
"id", l.ID,
210+
"product", l.ProductLine,
211+
"plan", l.PlanName,
212+
"tier", l.TierName,
213+
"expiry", l.NotAfter.UTC().Format(time.RFC822),
214+
)
203215
return &l, con, nil
204216
}

pkg/registry/proxyserver/licenserequest/storage.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"crypto/x509"
2222
"sort"
2323
"strings"
24+
"time"
2425

2526
proxyv1alpha1 "go.bytebuilders.dev/license-proxyserver/apis/proxyserver/v1alpha1"
2627
"go.bytebuilders.dev/license-proxyserver/pkg/common"
@@ -36,6 +37,7 @@ import (
3637
"k8s.io/apimachinery/pkg/util/sets"
3738
"k8s.io/apiserver/pkg/endpoints/request"
3839
"k8s.io/apiserver/pkg/registry/rest"
40+
"k8s.io/klog/v2"
3941
clustermeta "kmodules.xyz/client-go/cluster"
4042
clusterv1alpha1 "open-cluster-management.io/api/cluster/v1alpha1"
4143
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -143,6 +145,7 @@ func (r *Storage) Create(ctx context.Context, obj runtime.Object, _ rest.Validat
143145
}
144146
} else {
145147
// return blank response instead of error
148+
// typically license mounted via secret has expired
146149
in.Response = &proxyv1alpha1.LicenseRequestResponse{}
147150
}
148151

@@ -172,6 +175,14 @@ func (r *Storage) getLicense(features []string) (*v1alpha1.License, error) {
172175
if err != nil {
173176
return nil, err
174177
}
178+
179+
klog.InfoS("adding license",
180+
"id", l.ID,
181+
"product", l.ProductLine,
182+
"plan", l.PlanName,
183+
"tier", l.TierName,
184+
"expiry", l.NotAfter.UTC().Format(time.RFC822),
185+
)
175186
r.reg.Add(&l, c)
176187
return &l, nil
177188
}

pkg/storage/loader.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package storage
1919
import (
2020
"os"
2121
"path/filepath"
22+
"time"
2223

2324
verifier "go.bytebuilders.dev/license-verifier"
2425
"go.bytebuilders.dev/license-verifier/info"
@@ -68,7 +69,15 @@ func LoadDir(cid, dir string, reg *LicenseRegistry) error {
6869
if err != nil {
6970
klog.ErrorS(err, "Skipping", "file", filename)
7071
continue
71-
} else {
72+
} else if time.Until(license.NotAfter.Time) >= MinRemainingLife {
73+
klog.InfoS("adding license",
74+
"dir", dir,
75+
"id", license.ID,
76+
"product", license.ProductLine,
77+
"plan", license.PlanName,
78+
"tier", license.TierName,
79+
"expiry", license.NotAfter.UTC().Format(time.RFC822),
80+
)
7281
reg.Add(&license, nil)
7382
}
7483
}

pkg/storage/store.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@ import (
2525
"time"
2626

2727
"go.bytebuilders.dev/license-verifier/apis/licenses/v1alpha1"
28+
29+
"k8s.io/klog/v2"
2830
)
2931

30-
const minRemainingLife = 10 * time.Minute
32+
const (
33+
LicenseAcquisitionBuffer = 5 * time.Second
34+
MinRemainingLife = 5 * time.Minute
35+
)
3136

3237
// A LicenseQueue implements heap.Interface and holds Items.
3338
type LicenseQueue []*v1alpha1.License
@@ -109,13 +114,20 @@ func (r *LicenseRegistry) LicenseForFeature(feature string) (*v1alpha1.License,
109114
if !ok {
110115
return nil, false
111116
}
112-
now := time.Now().Add(minRemainingLife)
113117
for q.Len() > 0 {
114118
// ref: https://stackoverflow.com/a/63328950
115119
item := q[0]
116-
if now.After(item.NotAfter.Time) {
120+
if time.Until(item.NotAfter.Time) < MinRemainingLife {
117121
heap.Pop(&q)
118122
r.reg[feature] = q
123+
124+
klog.InfoS("removing license",
125+
"id", item.ID,
126+
"product", item.ProductLine,
127+
"plan", item.PlanName,
128+
"tier", item.TierName,
129+
"expiry", item.NotAfter.UTC().Format(time.RFC822),
130+
)
119131
r.removeFromStore(item)
120132
} else {
121133
return item, true
@@ -153,7 +165,7 @@ func (r *LicenseRegistry) List() []*Record {
153165
r.m.Lock()
154166
defer r.m.Unlock()
155167

156-
now := time.Now().Add(minRemainingLife)
168+
now := time.Now().Add(MinRemainingLife)
157169
out := make([]*Record, 0, len(r.store))
158170
for _, rec := range r.store {
159171
if rec.License.NotAfter.After(now) {

0 commit comments

Comments
 (0)