mirror of https://github.com/status-im/consul.git
feat: create a default namespace (#19681)
* feat: create a default namespace on leader * refactor: add comment and move inittenancy to leader file * refactor: rephrase comment
This commit is contained in:
parent
8fe0bd1cbd
commit
78f918a103
|
@ -5,6 +5,7 @@ package consul
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -16,20 +17,27 @@ import (
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
"github.com/armon/go-metrics/prometheus"
|
"github.com/armon/go-metrics/prometheus"
|
||||||
|
"github.com/oklog/ulid/v2"
|
||||||
|
"golang.org/x/time/rate"
|
||||||
|
"google.golang.org/protobuf/types/known/anypb"
|
||||||
|
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-uuid"
|
"github.com/hashicorp/go-uuid"
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/hashicorp/raft"
|
"github.com/hashicorp/raft"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
"golang.org/x/time/rate"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/metadata"
|
"github.com/hashicorp/consul/agent/metadata"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
"github.com/hashicorp/consul/agent/structs/aclfilter"
|
||||||
"github.com/hashicorp/consul/api"
|
"github.com/hashicorp/consul/api"
|
||||||
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
"github.com/hashicorp/consul/internal/storage"
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
"github.com/hashicorp/consul/logging"
|
"github.com/hashicorp/consul/logging"
|
||||||
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1"
|
||||||
"github.com/hashicorp/consul/types"
|
"github.com/hashicorp/consul/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -341,6 +349,12 @@ func (s *Server) establishLeadership(ctx context.Context) error {
|
||||||
s.startLogVerification(ctx)
|
s.startLogVerification(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.useV2Tenancy {
|
||||||
|
if err := s.initTenancy(ctx, s.resourceServiceServer.Backend); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if s.config.Reporting.License.Enabled && s.reportingManager != nil {
|
if s.config.Reporting.License.Enabled && s.reportingManager != nil {
|
||||||
s.reportingManager.StartReportingAgent()
|
s.reportingManager.StartReportingAgent()
|
||||||
}
|
}
|
||||||
|
@ -1449,3 +1463,61 @@ func (s *serversIntentionsAsConfigEntriesInfo) update(srv *metadata.Server) bool
|
||||||
// prevent continuing server evaluation
|
// prevent continuing server evaluation
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) initTenancy(ctx context.Context, b storage.Backend) error {
|
||||||
|
// we write these defaults directly to the storage backend
|
||||||
|
// without going through the resource service since tenancy
|
||||||
|
// validation hooks block writes to the default namespace
|
||||||
|
// and partition.
|
||||||
|
if err := s.createDefaultPartition(ctx, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.createDefaultNamespace(ctx, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) createDefaultNamespace(ctx context.Context, b storage.Backend) error {
|
||||||
|
readID := &pbresource.ID{
|
||||||
|
Type: pbtenancy.NamespaceType,
|
||||||
|
Name: resource.DefaultNamespaceName,
|
||||||
|
Tenancy: resource.DefaultPartitionedTenancy(),
|
||||||
|
}
|
||||||
|
|
||||||
|
read, err := b.Read(ctx, storage.StrongConsistency, readID)
|
||||||
|
|
||||||
|
if err != nil && !errors.Is(err, storage.ErrNotFound) {
|
||||||
|
return fmt.Errorf("failed to read the %q namespace: %v", resource.DefaultNamespaceName, err)
|
||||||
|
}
|
||||||
|
if read == nil && errors.Is(err, storage.ErrNotFound) {
|
||||||
|
nsData, err := anypb.New(&pbtenancy.Namespace{Description: "default namespace in default partition"})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a default namespace in default partition
|
||||||
|
nsID := &pbresource.ID{
|
||||||
|
Type: pbtenancy.NamespaceType,
|
||||||
|
Name: resource.DefaultNamespaceName,
|
||||||
|
Tenancy: resource.DefaultPartitionedTenancy(),
|
||||||
|
Uid: ulid.Make().String(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = b.WriteCAS(ctx, &pbresource.Resource{
|
||||||
|
Id: nsID,
|
||||||
|
Generation: ulid.Make().String(),
|
||||||
|
Data: nsData,
|
||||||
|
Metadata: map[string]string{
|
||||||
|
"generated_at": time.Now().Format(time.RFC3339),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to create the %q namespace: %v", resource.DefaultNamespaceName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.logger.Info("Created", "namespace", resource.DefaultNamespaceName)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright (c) HashiCorp, Inc.
|
||||||
|
// SPDX-License-Identifier: BUSL-1.1
|
||||||
|
|
||||||
|
//go:build !consulent
|
||||||
|
|
||||||
|
package consul
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) createDefaultPartition(ctx context.Context, b storage.Backend) error {
|
||||||
|
// no-op
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -5,7 +5,19 @@
|
||||||
|
|
||||||
package consul
|
package consul
|
||||||
|
|
||||||
import libserf "github.com/hashicorp/consul/lib/serf"
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
"github.com/hashicorp/consul/internal/storage"
|
||||||
|
libserf "github.com/hashicorp/consul/lib/serf"
|
||||||
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1"
|
||||||
|
"github.com/hashicorp/consul/testrpc"
|
||||||
|
)
|
||||||
|
|
||||||
func updateSerfTags(s *Server, key, value string) {
|
func updateSerfTags(s *Server, key, value string) {
|
||||||
libserf.UpdateTag(s.serfLAN, key, value)
|
libserf.UpdateTag(s.serfLAN, key, value)
|
||||||
|
@ -14,3 +26,41 @@ func updateSerfTags(s *Server, key, value string) {
|
||||||
libserf.UpdateTag(s.serfWAN, key, value)
|
libserf.UpdateTag(s.serfWAN, key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServer_InitTenancy(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
_, conf := testServerConfig(t)
|
||||||
|
deps := newDefaultDeps(t, conf)
|
||||||
|
deps.Experiments = []string{"v2tenancy"}
|
||||||
|
deps.Registry = NewTypeRegistry()
|
||||||
|
|
||||||
|
s, err := newServerWithDeps(t, conf, deps)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// first initTenancy call happens here
|
||||||
|
waitForLeaderEstablishment(t, s)
|
||||||
|
testrpc.WaitForLeader(t, s.RPC, "dc1")
|
||||||
|
|
||||||
|
nsID := &pbresource.ID{
|
||||||
|
Type: pbtenancy.NamespaceType,
|
||||||
|
Tenancy: resource.DefaultPartitionedTenancy(),
|
||||||
|
Name: resource.DefaultNamespaceName,
|
||||||
|
}
|
||||||
|
|
||||||
|
ns, err := s.resourceServiceServer.Backend.Read(context.Background(), storage.StrongConsistency, nsID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, resource.DefaultNamespaceName, ns.Id.Name)
|
||||||
|
|
||||||
|
// explicitly call initiTenancy to verify we do not re-create namespace
|
||||||
|
err = s.initTenancy(context.Background(), s.resourceServiceServer.Backend)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// read again
|
||||||
|
actual, err := s.resourceServiceServer.Backend.Read(context.Background(), storage.StrongConsistency, nsID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, ns.Id.Uid, actual.Id.Uid)
|
||||||
|
require.Equal(t, ns.Generation, actual.Generation)
|
||||||
|
require.Equal(t, ns.Version, actual.Version)
|
||||||
|
}
|
||||||
|
|
|
@ -20,9 +20,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
"github.com/hashicorp/consul/internal/auth"
|
"go.etcd.io/bbolt"
|
||||||
"github.com/hashicorp/consul/internal/mesh"
|
"golang.org/x/time/rate"
|
||||||
"github.com/hashicorp/consul/internal/multicluster"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
"google.golang.org/grpc/reflection"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
||||||
"github.com/hashicorp/go-connlimit"
|
"github.com/hashicorp/go-connlimit"
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-memdb"
|
"github.com/hashicorp/go-memdb"
|
||||||
|
@ -33,13 +37,7 @@ import (
|
||||||
walmetrics "github.com/hashicorp/raft-wal/metrics"
|
walmetrics "github.com/hashicorp/raft-wal/metrics"
|
||||||
"github.com/hashicorp/raft-wal/verifier"
|
"github.com/hashicorp/raft-wal/verifier"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
"go.etcd.io/bbolt"
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
|
||||||
"google.golang.org/grpc/reflection"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul-net-rpc/net/rpc"
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/acl/resolver"
|
"github.com/hashicorp/consul/acl/resolver"
|
||||||
"github.com/hashicorp/consul/agent/blockingquery"
|
"github.com/hashicorp/consul/agent/blockingquery"
|
||||||
|
@ -73,9 +71,12 @@ import (
|
||||||
"github.com/hashicorp/consul/agent/rpc/peering"
|
"github.com/hashicorp/consul/agent/rpc/peering"
|
||||||
"github.com/hashicorp/consul/agent/structs"
|
"github.com/hashicorp/consul/agent/structs"
|
||||||
"github.com/hashicorp/consul/agent/token"
|
"github.com/hashicorp/consul/agent/token"
|
||||||
|
"github.com/hashicorp/consul/internal/auth"
|
||||||
"github.com/hashicorp/consul/internal/catalog"
|
"github.com/hashicorp/consul/internal/catalog"
|
||||||
"github.com/hashicorp/consul/internal/controller"
|
"github.com/hashicorp/consul/internal/controller"
|
||||||
|
"github.com/hashicorp/consul/internal/mesh"
|
||||||
proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot"
|
proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot"
|
||||||
|
"github.com/hashicorp/consul/internal/multicluster"
|
||||||
"github.com/hashicorp/consul/internal/resource"
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
"github.com/hashicorp/consul/internal/resource/demo"
|
"github.com/hashicorp/consul/internal/resource/demo"
|
||||||
"github.com/hashicorp/consul/internal/resource/reaper"
|
"github.com/hashicorp/consul/internal/resource/reaper"
|
||||||
|
|
|
@ -11,10 +11,11 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/hashicorp/serf/coordinate"
|
"github.com/hashicorp/serf/coordinate"
|
||||||
"github.com/hashicorp/serf/serf"
|
"github.com/hashicorp/serf/serf"
|
||||||
"google.golang.org/grpc"
|
|
||||||
|
|
||||||
"github.com/hashicorp/consul/acl"
|
"github.com/hashicorp/consul/acl"
|
||||||
"github.com/hashicorp/consul/agent/consul/reporting"
|
"github.com/hashicorp/consul/agent/consul/reporting"
|
||||||
|
|
Loading…
Reference in New Issue