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:
Poonam Jadhav 2023-11-22 14:32:57 -05:00 committed by GitHub
parent 8fe0bd1cbd
commit 78f918a103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 12 deletions

View File

@ -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
}

17
agent/consul/leader_ce.go Normal file
View File

@ -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
}

View File

@ -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)
}

View File

@ -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"

View File

@ -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"