Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v9] Correctly handle Firestore pagination with DocumentID cursors #13757

Merged
merged 10 commits into from
Sep 16, 2022
47 changes: 26 additions & 21 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module github.com/gravitational/teleport
go 1.17

require (
cloud.google.com/go v0.100.2 // indirect
cloud.google.com/go/firestore v1.2.0
cloud.google.com/go/iam v0.1.1
cloud.google.com/go/storage v1.10.0
cloud.google.com/go v0.103.0 // indirect
cloud.google.com/go/firestore v1.6.1
cloud.google.com/go/iam v0.3.0
cloud.google.com/go/storage v1.23.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
Expand Down Expand Up @@ -42,7 +42,7 @@ require (
github.com/gokyle/hotp v0.0.0-20160218004637-c180d57d286b
github.com/golang/protobuf v1.5.2
github.com/google/btree v1.0.1
github.com/google/go-cmp v0.5.7
github.com/google/go-cmp v0.5.8
github.com/google/gops v0.3.14
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.4.2
Expand Down Expand Up @@ -103,19 +103,19 @@ require (
go.opentelemetry.io/otel/trace v1.7.0
go.opentelemetry.io/proto/otlp v0.16.0
go.uber.org/atomic v1.7.0
golang.org/x/crypto v0.0.0-20220126234351-aa10faf2a1f8
golang.org/x/mod v0.4.2
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3
golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced
golang.org/x/oauth2 v0.0.0-20220808172628-8227340efae7
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff
google.golang.org/api v0.65.0
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5
google.golang.org/grpc v1.46.0
google.golang.org/protobuf v1.28.0
golang.org/x/tools v0.1.10
google.golang.org/api v0.91.0
google.golang.org/genproto v0.0.0-20220808204814-fd01256a5276
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.1
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/ini.v1 v1.62.0
gopkg.in/square/go-jose.v2 v2.5.1
Expand All @@ -126,7 +126,12 @@ require (
)

require (
cloud.google.com/go/compute v0.1.0 // indirect
cloud.google.com/go/compute v1.8.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/go-type-adapters v1.0.0 // indirect
)

require (
github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
Expand Down Expand Up @@ -167,7 +172,7 @@ require (
github.com/golang/snappy v0.0.3 // indirect
github.com/google/certificate-transparency-go v1.0.21 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
github.com/googleapis/gax-go/v2 v2.5.1 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect
github.com/gorilla/handlers v1.5.1 // indirect
Expand Down Expand Up @@ -234,16 +239,16 @@ require (
go.opentelemetry.io/otel/metric v0.28.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/klog/v2 v2.30.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
k8s.io/utils v0.0.0-20211116205334-6203023598ed // indirect
k8s.io/utils v0.0.0-20211116205334-6203023598ed
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
Expand Down
164 changes: 129 additions & 35 deletions go.sum

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4404,12 +4404,12 @@ func testRotateChangeSigningAlg(t *testing.T, suite *integrationTestSuite) {

t.Log("change signature algorithm with custom config value and manual rotation")
// Change the signing algorithm in config file.
signingAlg := ssh.SigAlgoRSA
signingAlg := ssh.KeyAlgoRSA
config.CASignatureAlgorithm = &signingAlg
svc, cancel = restart(svc, cancel)
// Do a manual rotation - this should change the signing algorithm.
svc = rotate(svc, types.RotationModeManual)
assertSigningAlg(svc, ssh.SigAlgoRSA)
assertSigningAlg(svc, ssh.KeyAlgoRSA)

t.Log("preserve signature algorithm with empty config value and manual rotation")
// Unset the config value.
Expand All @@ -4419,7 +4419,7 @@ func testRotateChangeSigningAlg(t *testing.T, suite *integrationTestSuite) {
// Do a manual rotation - this should leave the signing algorithm
// unaffected because config value is not set.
svc = rotate(svc, types.RotationModeManual)
assertSigningAlg(svc, ssh.SigAlgoRSA)
assertSigningAlg(svc, ssh.KeyAlgoRSA)

// shut down the service
cancel()
Expand Down
10 changes: 5 additions & 5 deletions lib/auth/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ func TestCASigningAlg(t *testing.T) {
auth, err := Init(conf)
require.NoError(t, err)
defer auth.Close()
verifyCAs(auth, ssh.SigAlgoRSASHA2512)
verifyCAs(auth, ssh.KeyAlgoRSASHA2512)

require.NoError(t, auth.Close())

Expand All @@ -475,19 +475,19 @@ func TestCASigningAlg(t *testing.T) {
conf.DataDir = t.TempDir()

// Start a new server with non-default signing alg.
signingAlg := ssh.SigAlgoRSA
signingAlg := ssh.KeyAlgoRSA
conf.CASigningAlg = &signingAlg
auth, err = Init(conf)
require.NoError(t, err)
defer auth.Close()
verifyCAs(auth, ssh.SigAlgoRSA)
verifyCAs(auth, ssh.KeyAlgoRSA)

// Start again, using a different alg. This should not change the existing
// CA.
signingAlg = ssh.SigAlgoRSASHA2256
signingAlg = ssh.KeyAlgoRSASHA2256
auth, err = Init(conf)
require.NoError(t, err)
verifyCAs(auth, ssh.SigAlgoRSA)
verifyCAs(auth, ssh.KeyAlgoRSA)
}

// TestPresets tests behavior of presets
Expand Down
54 changes: 21 additions & 33 deletions lib/backend/firestore/firestorebk.go
Original file line number Diff line number Diff line change
Expand Up @@ -757,58 +757,46 @@ func (b *Backend) getIndexParent() string {
}

func (b *Backend) ensureIndexes(adminSvc *apiv1.FirestoreAdminClient) error {
tuples := []*IndexTuple{{
FirstField: keyDocProperty,
SecondField: expiresDocProperty,
SecondFieldOrder: adminpb.Index_IndexField_ASCENDING,
}}
tuples := IndexList{}
tuples.Index(Field(keyDocProperty, adminpb.Index_IndexField_ASCENDING), Field(expiresDocProperty, adminpb.Index_IndexField_ASCENDING))
return EnsureIndexes(b.clientContext, adminSvc, tuples, b.getIndexParent())
}

type IndexTuple struct {
FirstField string
SecondField string
SecondFieldOrder adminpb.Index_IndexField_Order
type IndexList [][]*adminpb.Index_IndexField

func (l *IndexList) Index(fields ...*adminpb.Index_IndexField) {
list := []*adminpb.Index_IndexField{}
list = append(list, fields...)
*l = append(*l, list)
}

func Field(name string, order adminpb.Index_IndexField_Order) *adminpb.Index_IndexField {
return &adminpb.Index_IndexField{
FieldPath: name,
ValueMode: &adminpb.Index_IndexField_Order_{
Order: order,
},
}
}

type indexTask struct {
operation *apiv1.CreateIndexOperation
tuple *IndexTuple
tuple []*adminpb.Index_IndexField
}

// EnsureIndexes is a function used by Firestore events and backend to generate indexes and will block until
// indexes are reported as created
func EnsureIndexes(ctx context.Context, adminSvc *apiv1.FirestoreAdminClient, tuples []*IndexTuple, indexParent string) error {
func EnsureIndexes(ctx context.Context, adminSvc *apiv1.FirestoreAdminClient, tuples IndexList, indexParent string) error {
l := log.WithFields(log.Fields{trace.Component: BackendName})

ascendingFieldOrder := &adminpb.Index_IndexField_Order_{
Order: adminpb.Index_IndexField_ASCENDING,
}

var tasks []indexTask

// create the indexes
for _, tuple := range tuples {
secondFieldOrder := &adminpb.Index_IndexField_Order_{
Order: tuple.SecondFieldOrder,
}

fields := []*adminpb.Index_IndexField{
{
FieldPath: tuple.FirstField,
ValueMode: ascendingFieldOrder,
},
{
FieldPath: tuple.SecondField,
ValueMode: secondFieldOrder,
},
}
l.Infof("%v", fields)
operation, err := adminSvc.CreateIndex(ctx, &adminpb.CreateIndexRequest{
Parent: indexParent,
Index: &adminpb.Index{
QueryScope: adminpb.Index_COLLECTION,
Fields: fields,
Fields: tuple,
},
})
if err != nil && status.Code(err) != codes.AlreadyExists {
Expand Down Expand Up @@ -857,7 +845,7 @@ func waitOnIndexCreation(ctx context.Context, l *log.Entry, task indexTask) erro
if err != nil {
return trace.Wrap(err)
}
l.Infof("Creating index for tuple %s-%s with name %s.", task.tuple.FirstField, task.tuple.SecondField, meta.Index)
l.Infof("Creating index for tuple %v with name %s.", task.tuple, meta.Index)

_, err = task.operation.Wait(ctx)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions lib/config/fileconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ import (
)

var validCASigAlgos = []string{
ssh.SigAlgoRSA,
ssh.SigAlgoRSASHA2256,
ssh.SigAlgoRSASHA2512,
ssh.KeyAlgoRSA,
ssh.KeyAlgoRSASHA2256,
ssh.KeyAlgoRSASHA2512,
}

// FileConfig structre represents the teleport configuration stored in a config file
Expand Down
2 changes: 1 addition & 1 deletion lib/defaults/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ var (

// CASignatureAlgorithm is the default signing algorithm to use when
// creating new SSH CAs.
CASignatureAlgorithm = ssh.SigAlgoRSASHA2512
CASignatureAlgorithm = ssh.KeyAlgoRSASHA2512

// SessionControlTimeout is the maximum amount of time a controlled session
// may persist after contact with the auth server is lost (sessctl semaphore
Expand Down