-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't apply license state for oss builds. (#3847)
This change ensure that license state is only applied and warnings about expiry only printed for `!oss` builds.
- Loading branch information
1 parent
00a2914
commit 98880f8
Showing
5 changed files
with
177 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// +build oss | ||
|
||
/* | ||
* Copyright 2018 Dgraph Labs, Inc. and Contributors | ||
* | ||
* 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 zero | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/dgraph-io/badger/y" | ||
) | ||
|
||
// dummy function as enterprise features are not available in oss binary. | ||
func (n *node) proposeTrialLicense() error { | ||
return nil | ||
} | ||
|
||
// periodically checks the validity of the enterprise license and updates the membership state. | ||
func (n *node) updateEnterpriseState(closer *y.Closer) { | ||
closer.Done() | ||
} | ||
|
||
func (st *state) applyEnterpriseLicense(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(http.StatusNotFound) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// +build !oss | ||
|
||
/* | ||
* Copyright 2018 Dgraph Labs, Inc. and Contributors | ||
* | ||
* Licensed under the Dgraph Community License (the "License"); you | ||
* may not use this file except in compliance with the License. You | ||
* may obtain a copy of the License at | ||
* | ||
* https://github.com/dgraph-io/dgraph/blob/master/licenses/DCL.txt | ||
*/ | ||
|
||
package zero | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"math" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/dgraph-io/badger/y" | ||
"github.com/dgraph-io/dgraph/protos/pb" | ||
"github.com/dgraph-io/dgraph/x" | ||
humanize "github.com/dustin/go-humanize" | ||
"github.com/gogo/protobuf/proto" | ||
"github.com/golang/glog" | ||
"golang.org/x/net/context" | ||
) | ||
|
||
// proposeTrialLicense proposes an enterprise license valid for 30 days. | ||
func (n *node) proposeTrialLicense() error { | ||
// Apply enterprise license valid for 30 days from now. | ||
proposal := &pb.ZeroProposal{ | ||
License: &pb.License{ | ||
MaxNodes: math.MaxUint64, | ||
ExpiryTs: time.Now().UTC().Add(humanize.Month).Unix(), | ||
}, | ||
} | ||
err := n.proposeAndWait(context.Background(), proposal) | ||
if err != nil { | ||
return err | ||
|
||
} | ||
glog.Infof("Enterprise state proposed to the cluster: %v", proposal) | ||
return nil | ||
} | ||
|
||
func (s *Server) license() *pb.License { | ||
s.RLock() | ||
defer s.RUnlock() | ||
return proto.Clone(s.state.GetLicense()).(*pb.License) | ||
} | ||
|
||
func (s *Server) expireLicense() { | ||
s.Lock() | ||
defer s.Unlock() | ||
s.state.License.Enabled = false | ||
} | ||
|
||
// periodically checks the validity of the enterprise license and | ||
// 1. Sets license.Enabled to false in membership state if license has expired. | ||
// 2. Prints out warning once every day a week before the license is set to expire. | ||
func (n *node) updateEnterpriseState(closer *y.Closer) { | ||
defer closer.Done() | ||
|
||
interval := 5 * time.Second | ||
ticker := time.NewTicker(interval) | ||
defer ticker.Stop() | ||
|
||
intervalsInDay := int64(24*time.Hour) / int64(interval) | ||
var counter int64 | ||
for { | ||
select { | ||
case <-ticker.C: | ||
counter++ | ||
license := n.server.license() | ||
if !license.GetEnabled() { | ||
continue | ||
} | ||
|
||
expiry := time.Unix(license.GetExpiryTs(), 0).UTC() | ||
timeToExpire := expiry.Sub(time.Now().UTC()) | ||
// We only want to print this log once a day. | ||
if counter%intervalsInDay == 0 && timeToExpire > 0 && timeToExpire < humanize.Week { | ||
glog.Warningf("Enterprise license is going to expire in %s.", humanize.Time(expiry)) | ||
} | ||
|
||
active := time.Now().UTC().Before(expiry) | ||
if !active { | ||
n.server.expireLicense() | ||
glog.Warningf("Enterprise license has expired and enterprise features would be " + | ||
"disabled now. Talk to us at [email protected] to get a new license.") | ||
} | ||
case <-closer.HasBeenClosed(): | ||
return | ||
} | ||
} | ||
} | ||
|
||
// applyEnterpriseLicense accepts a PGP message as a POST request body, verifies that it was | ||
// signed using our private key and applies the license which has maxNodes and Expiry to the | ||
// cluster. | ||
func (st *state) applyEnterpriseLicense(w http.ResponseWriter, r *http.Request) { | ||
x.AddCorsHeaders(w) | ||
if r.Method == "OPTIONS" { | ||
return | ||
} | ||
if r.Method != http.MethodPost { | ||
w.WriteHeader(http.StatusBadRequest) | ||
x.SetStatus(w, x.ErrorInvalidMethod, "Invalid method") | ||
return | ||
} | ||
|
||
w.Header().Set("Content-Type", "application/json") | ||
b, err := ioutil.ReadAll(r.Body) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
x.SetStatus(w, x.ErrorInvalidRequest, err.Error()) | ||
return | ||
} | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute) | ||
defer cancel() | ||
if err := st.zero.applyLicense(ctx, bytes.NewReader(b)); err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
x.SetStatus(w, x.ErrorInvalidRequest, err.Error()) | ||
return | ||
} | ||
x.SetStatus(w, x.Success, "Done") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,8 +23,6 @@ import ( | |
"sync" | ||
"time" | ||
|
||
"github.com/dustin/go-humanize" | ||
|
||
otrace "go.opencensus.io/trace" | ||
"golang.org/x/net/context" | ||
|
||
|
@@ -275,45 +273,6 @@ func (s *Server) updateZeroLeader() { | |
} | ||
} | ||
|
||
// updateEnterpriseState periodically checks the validity of the enterprise license | ||
// based on its expiry. | ||
func (s *Server) updateEnterpriseState() { | ||
s.Lock() | ||
defer s.Unlock() | ||
|
||
// Return early if license is not enabled. This would happen when user didn't supply us a | ||
// license file yet. | ||
if s.state.GetLicense() == nil { | ||
return | ||
} | ||
|
||
enabled := s.state.GetLicense().GetEnabled() | ||
expiry := time.Unix(s.state.License.ExpiryTs, 0) | ||
s.state.License.Enabled = time.Now().Before(expiry) | ||
if enabled && !s.state.License.Enabled { | ||
// License was enabled earlier and has just now been disabled. | ||
glog.Infof("Enterprise license has expired and enterprise features would be disabled now. " + | ||
"Talk to us at [email protected] to get a new license.") | ||
} | ||
} | ||
|
||
// Prints out an info log about the expiry of the license if its about to expire in less than a | ||
// week. | ||
func (s *Server) licenseExpiryWarning() { | ||
s.RLock() | ||
defer s.RUnlock() | ||
|
||
if s.state.GetLicense() == nil { | ||
return | ||
} | ||
enabled := s.state.GetLicense().GetEnabled() | ||
expiry := time.Unix(s.state.License.ExpiryTs, 0) | ||
timeToExpire := expiry.Sub(time.Now()) | ||
if enabled && timeToExpire > 0 && timeToExpire < humanize.Week { | ||
glog.Infof("Enterprise license is going to expire in %s.", humanize.Time(expiry)) | ||
} | ||
} | ||
|
||
func (s *Server) removeZero(nodeId uint64) { | ||
s.Lock() | ||
defer s.Unlock() | ||
|
@@ -786,7 +745,7 @@ func (s *Server) latestMembershipState(ctx context.Context) (*pb.MembershipState | |
return ms, nil | ||
} | ||
|
||
func (s *Server) applyEnterpriseLicense(ctx context.Context, signedData io.Reader) error { | ||
func (s *Server) applyLicense(ctx context.Context, signedData io.Reader) error { | ||
var l license | ||
if err := verifySignature(signedData, strings.NewReader(publicKey), &l); err != nil { | ||
return errors.Wrapf(err, "while extracting enterprise details from the license") | ||
|