Service environment (#23443)
* fix fileutils.TestFindFile on MacOS * introduce model.ExternalServiceEnvironment * pick license public key from external service env * pick Stripe public key from external service env * pick Rudder key from external service env * configure Sentry DSN from external service env * always log external_service_environment, Unsetenv * clear faked BuildEnv, improve logging * strip out unset GOTAGS * fix Sentry tests * simplify to just ServiceEnvironment * relocate ServiceEnvironment in client config * initialize CWS URLs based on service environment * unset rudder key for boards dev * harden service environment to avoid accidental production * fix TestSentry again * fix DEFAULT -> ENTERPRISE * s/dev/test when naming playbooks rudder key * simplify boards rudder key switch * use uniform rudderKey variable names * retain compatibility with existing pipeline * reduce to just production/test * unit test with valid test license * simplify Playbooks telemetry initialization * restore dev service environment * emit ServiceEnvironment when running e2e tests
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6c82605df0
Коммит
305fac6507
@@ -640,6 +640,9 @@ func TestNoticeValidation(t *testing.T) {
|
||||
model.BuildNumber = tt.args.serverVersion
|
||||
if model.BuildNumber == "" {
|
||||
model.BuildNumber = "5.26.1"
|
||||
defer func() {
|
||||
model.BuildNumber = ""
|
||||
}()
|
||||
}
|
||||
if ok, err := noticeMatchesConditions(
|
||||
th.App.Config(),
|
||||
|
||||
@@ -74,8 +74,12 @@ import (
|
||||
"github.com/mattermost/mattermost-server/server/v8/platform/shared/templates"
|
||||
)
|
||||
|
||||
// declaring this as var to allow overriding in tests
|
||||
var SentryDSN = "placeholder_sentry_dsn"
|
||||
var SentryDSN = "https://9d7c9cccf549479799f880bcf4f26323@o94110.ingest.sentry.io/5212327"
|
||||
|
||||
// This is a placeholder to allow the existing release pipelines to run without failing to insert
|
||||
// the key that's now hard-coded above. Remove this once we converge on the unified delivery
|
||||
// pipeline in GitHub.
|
||||
var _ = "placeholder_sentry_dsn"
|
||||
|
||||
type Server struct {
|
||||
// RootRouter is the starting point for all HTTP requests to the server.
|
||||
@@ -294,9 +298,10 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry {
|
||||
if strings.Contains(SentryDSN, "placeholder") {
|
||||
mlog.Warn("Sentry reporting is enabled, but SENTRY_DSN is not set. Disabling reporting.")
|
||||
} else {
|
||||
switch model.GetServiceEnvironment() {
|
||||
case model.ServiceEnvironmentDev:
|
||||
mlog.Warn("Sentry reporting is enabled, but service environment is dev. Disabling reporting.")
|
||||
case model.ServiceEnvironmentProduction, model.ServiceEnvironmentTest:
|
||||
if err2 := sentry.Init(sentry.ClientOptions{
|
||||
Dsn: SentryDSN,
|
||||
Release: model.BuildHash,
|
||||
@@ -424,6 +429,7 @@ func NewServer(options ...Option) (*Server, error) {
|
||||
mlog.String("build_date", model.BuildDate),
|
||||
mlog.String("build_hash", model.BuildHash),
|
||||
mlog.String("build_hash_enterprise", model.BuildHashEnterprise),
|
||||
mlog.String("service_environment", model.GetServiceEnvironment()),
|
||||
)
|
||||
if model.BuildEnterpriseReady == "true" {
|
||||
mlog.Info("Enterprise Build", mlog.Bool("enterprise_build", true))
|
||||
@@ -907,11 +913,15 @@ func (s *Server) Start() error {
|
||||
|
||||
var handler http.Handler = s.RootRouter
|
||||
|
||||
if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry && !strings.Contains(SentryDSN, "placeholder") {
|
||||
sentryHandler := sentryhttp.New(sentryhttp.Options{
|
||||
Repanic: true,
|
||||
})
|
||||
handler = sentryHandler.Handle(handler)
|
||||
switch model.GetServiceEnvironment() {
|
||||
case model.ServiceEnvironmentProduction, model.ServiceEnvironmentTest:
|
||||
if *s.platform.Config().LogSettings.EnableDiagnostics && *s.platform.Config().LogSettings.EnableSentry {
|
||||
sentryHandler := sentryhttp.New(sentryhttp.Options{
|
||||
Repanic: true,
|
||||
})
|
||||
handler = sentryHandler.Handle(handler)
|
||||
}
|
||||
case model.ServiceEnvironmentDev:
|
||||
}
|
||||
|
||||
if allowedOrigins := *s.platform.Config().ServiceSettings.AllowCorsFrom; allowedOrigins != "" {
|
||||
|
||||
@@ -395,6 +395,22 @@ func TestSentry(t *testing.T) {
|
||||
}}
|
||||
testDir, _ := fileutils.FindDir("tests")
|
||||
|
||||
setSentryDSN := func(t *testing.T, dsn *sentry.Dsn) {
|
||||
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest)
|
||||
|
||||
// Allow Playbooks to startup
|
||||
oldBuildHash := model.BuildHash
|
||||
model.BuildHash = "dev"
|
||||
|
||||
oldSentryDSN := SentryDSN
|
||||
SentryDSN = dsn.String()
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("MM_SERVICEENVIRONMENT")
|
||||
model.BuildHash = oldBuildHash
|
||||
SentryDSN = oldSentryDSN
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("sentry is disabled, should not receive a report", func(t *testing.T) {
|
||||
data := make(chan bool, 1)
|
||||
|
||||
@@ -408,7 +424,7 @@ func TestSentry(t *testing.T) {
|
||||
_, port, _ := net.SplitHostPort(server.Listener.Addr().String())
|
||||
dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port))
|
||||
require.NoError(t, err)
|
||||
SentryDSN = dsn.String()
|
||||
setSentryDSN(t, dsn)
|
||||
|
||||
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
||||
*cfg.ServiceSettings.ListenAddress = "localhost:0"
|
||||
@@ -452,7 +468,7 @@ func TestSentry(t *testing.T) {
|
||||
_, port, _ := net.SplitHostPort(server.Listener.Addr().String())
|
||||
dsn, err := sentry.NewDsn(fmt.Sprintf("http://test:test@localhost:%s/123", port))
|
||||
require.NoError(t, err)
|
||||
SentryDSN = dsn.String()
|
||||
setSentryDSN(t, dsn)
|
||||
|
||||
s, err := newServerWithConfig(t, func(cfg *model.Config) {
|
||||
*cfg.ServiceSettings.ListenAddress = "localhost:0"
|
||||
|
||||
@@ -102,7 +102,7 @@ func TestFindFile(t *testing.T) {
|
||||
fmt.Sprintf("%s: quadruple-nested subdirectory of containing directory", fileName),
|
||||
&tmpDir5,
|
||||
fileName,
|
||||
filePath,
|
||||
filePathResolved,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
@@ -74,6 +74,13 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) {
|
||||
plaintext := decoded[:len(decoded)-256]
|
||||
signature := decoded[len(decoded)-256:]
|
||||
|
||||
var publicKey []byte
|
||||
switch model.GetServiceEnvironment() {
|
||||
case model.ServiceEnvironmentProduction:
|
||||
publicKey = productionPublicKey
|
||||
case model.ServiceEnvironmentTest, model.ServiceEnvironmentDev:
|
||||
publicKey = testPublicKey
|
||||
}
|
||||
block, _ := pem.Decode(publicKey)
|
||||
|
||||
public, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
//go:build !testlicensekey
|
||||
|
||||
package utils
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed license-public-key.txt
|
||||
var publicKey []byte
|
||||
var productionPublicKey []byte
|
||||
|
||||
//go:embed license-public-key-test.txt
|
||||
var testPublicKey []byte
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
//go:build testlicensekey
|
||||
|
||||
package utils
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed license-public-key-test.txt
|
||||
var publicKey []byte
|
||||
@@ -9,10 +9,13 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost-server/server/public/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var validTestLicense = []byte("eyJpZCI6InpvZ3c2NW44Z2lmajVkbHJoYThtYnUxcGl3IiwiaXNzdWVkX2F0IjoxNjg0Nzg3MzcxODY5LCJzdGFydHNfYXQiOjE2ODQ3ODczNzE4NjksImV4cGlyZXNfYXQiOjIwMDA0MDY1MzgwMDAsInNrdV9uYW1lIjoiUHJvZmVzc2lvbmFsIiwic2t1X3Nob3J0X25hbWUiOiJwcm9mZXNzaW9uYWwiLCJjdXN0b21lciI6eyJpZCI6InA5dW4zNjlhNjdnaW1qNHlkNmk2aWIzOXdoIiwibmFtZSI6Ik1hdHRlcm1vc3QiLCJlbWFpbCI6ImpvcmFtQG1hdHRlcm1vc3QuY29tIiwiY29tcGFueSI6Ik1hdHRlcm1vc3QifSwiZmVhdHVyZXMiOnsidXNlcnMiOjIwMDAwMCwibGRhcCI6dHJ1ZSwibGRhcF9ncm91cHMiOmZhbHNlLCJtZmEiOnRydWUsImdvb2dsZV9vYXV0aCI6dHJ1ZSwib2ZmaWNlMzY1X29hdXRoIjp0cnVlLCJjb21wbGlhbmNlIjpmYWxzZSwiY2x1c3RlciI6dHJ1ZSwibWV0cmljcyI6dHJ1ZSwibWhwbnMiOnRydWUsInNhbWwiOnRydWUsImVsYXN0aWNfc2VhcmNoIjp0cnVlLCJhbm5vdW5jZW1lbnQiOnRydWUsInRoZW1lX21hbmFnZW1lbnQiOmZhbHNlLCJlbWFpbF9ub3RpZmljYXRpb25fY29udGVudHMiOmZhbHNlLCJkYXRhX3JldGVudGlvbiI6ZmFsc2UsIm1lc3NhZ2VfZXhwb3J0IjpmYWxzZSwiY3VzdG9tX3Blcm1pc3Npb25zX3NjaGVtZXMiOmZhbHNlLCJjdXN0b21fdGVybXNfb2Zfc2VydmljZSI6ZmFsc2UsImd1ZXN0X2FjY291bnRzIjp0cnVlLCJndWVzdF9hY2NvdW50c19wZXJtaXNzaW9ucyI6dHJ1ZSwiaWRfbG9hZGVkIjpmYWxzZSwibG9ja190ZWFtbWF0ZV9uYW1lX2Rpc3BsYXkiOmZhbHNlLCJjbG91ZCI6ZmFsc2UsInNoYXJlZF9jaGFubmVscyI6ZmFsc2UsInJlbW90ZV9jbHVzdGVyX3NlcnZpY2UiOmZhbHNlLCJvcGVuaWQiOnRydWUsImVudGVycHJpc2VfcGx1Z2lucyI6dHJ1ZSwiYWR2YW5jZWRfbG9nZ2luZyI6dHJ1ZSwiZnV0dXJlX2ZlYXR1cmVzIjpmYWxzZX0sImlzX3RyaWFsIjp0cnVlLCJpc19nb3Zfc2t1IjpmYWxzZX0bEOVk2GdE1kSWKJ3dENWnkj0htY6QyXTtNA5hqnQ71Uc6teqXc7htHAxrnT/hV42xu+G24OMrAIsQtX4NjFSX6jvehIMRL5II3RPXYhHKUd2wruQ5ITEh1htFb5DgOJW3tvBdMmXt09nXjLRS1UYJ7ZsX3mU0uQndt7qfMriGAkk71veYuUJgztB3MsV7lRWB+8ZTp6WJ7RH+uWnuDspiA8B85mLnyuoCDokYksF2uIb+CtPGBTUB6qSOgxBBJxu5qftQXISCDAWY4O8lCrN3p5HCA/zf/rSRRNtet06QFobbjUDI4B7ZEAescKBKoHpP6nZPhg4KmhnkUi/o04ox")
|
||||
|
||||
func TestValidateLicense(t *testing.T) {
|
||||
t.Run("should fail with junk data", func(t *testing.T) {
|
||||
b1 := []byte("junk")
|
||||
@@ -24,7 +27,7 @@ func TestValidateLicense(t *testing.T) {
|
||||
require.False(t, ok, "should have failed - bad license")
|
||||
})
|
||||
|
||||
t.Run("should not panic on shorted than expected input", func(t *testing.T) {
|
||||
t.Run("should not panic on shorter than expected input", func(t *testing.T) {
|
||||
var licenseData bytes.Buffer
|
||||
var inputData []byte
|
||||
|
||||
@@ -62,6 +65,33 @@ func TestValidateLicense(t *testing.T) {
|
||||
require.False(t, ok)
|
||||
require.Empty(t, str)
|
||||
})
|
||||
|
||||
t.Run("should reject invalid license in test service environment", func(t *testing.T) {
|
||||
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest)
|
||||
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
|
||||
|
||||
ok, str := LicenseValidator.ValidateLicense(nil)
|
||||
require.False(t, ok)
|
||||
require.Empty(t, str)
|
||||
})
|
||||
|
||||
t.Run("should validate valid test license in test service environment", func(t *testing.T) {
|
||||
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentTest)
|
||||
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
|
||||
|
||||
ok, str := LicenseValidator.ValidateLicense(validTestLicense)
|
||||
require.True(t, ok)
|
||||
require.NotEmpty(t, str)
|
||||
})
|
||||
|
||||
t.Run("should reject valid test license in production service environment", func(t *testing.T) {
|
||||
os.Setenv("MM_SERVICEENVIRONMENT", model.ServiceEnvironmentProduction)
|
||||
defer os.Unsetenv("MM_SERVICEENVIRONMENT")
|
||||
|
||||
ok, str := LicenseValidator.ValidateLicense(validTestLicense)
|
||||
require.False(t, ok)
|
||||
require.Empty(t, str)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetLicenseFileLocation(t *testing.T) {
|
||||
|
||||
Ссылка в новой задаче
Block a user