Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
a9dc919f
Commit
a9dc919f
authored
Dec 06, 2018
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Look up service accounts from informer before trying live lookup
parent
0351853e
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
105 additions
and
9 deletions
+105
-9
server.go
cmd/kube-apiserver/app/server.go
+6
-1
tokengetter.go
pkg/controller/serviceaccount/tokengetter.go
+16
-3
BUILD
pkg/serviceaccount/BUILD
+2
-0
jwt_test.go
pkg/serviceaccount/jwt_test.go
+35
-1
BUILD
test/integration/auth/BUILD
+2
-0
svcaccttoken_test.go
test/integration/auth/svcaccttoken_test.go
+34
-1
service_account_test.go
test/integration/serviceaccount/service_account_test.go
+10
-3
No files found.
cmd/kube-apiserver/app/server.go
View file @
a9dc919f
...
@@ -504,7 +504,12 @@ func buildGenericConfig(
...
@@ -504,7 +504,12 @@ func buildGenericConfig(
func
BuildAuthenticator
(
s
*
options
.
ServerRunOptions
,
extclient
clientgoclientset
.
Interface
,
versionedInformer
clientgoinformers
.
SharedInformerFactory
)
(
authenticator
.
Request
,
*
spec
.
SecurityDefinitions
,
error
)
{
func
BuildAuthenticator
(
s
*
options
.
ServerRunOptions
,
extclient
clientgoclientset
.
Interface
,
versionedInformer
clientgoinformers
.
SharedInformerFactory
)
(
authenticator
.
Request
,
*
spec
.
SecurityDefinitions
,
error
)
{
authenticatorConfig
:=
s
.
Authentication
.
ToAuthenticationConfig
()
authenticatorConfig
:=
s
.
Authentication
.
ToAuthenticationConfig
()
if
s
.
Authentication
.
ServiceAccounts
.
Lookup
{
if
s
.
Authentication
.
ServiceAccounts
.
Lookup
{
authenticatorConfig
.
ServiceAccountTokenGetter
=
serviceaccountcontroller
.
NewGetterFromClient
(
extclient
)
authenticatorConfig
.
ServiceAccountTokenGetter
=
serviceaccountcontroller
.
NewGetterFromClient
(
extclient
,
versionedInformer
.
Core
()
.
V1
()
.
Secrets
()
.
Lister
(),
versionedInformer
.
Core
()
.
V1
()
.
ServiceAccounts
()
.
Lister
(),
versionedInformer
.
Core
()
.
V1
()
.
Pods
()
.
Lister
(),
)
}
}
authenticatorConfig
.
BootstrapTokenAuthenticator
=
bootstrap
.
NewTokenAuthenticator
(
authenticatorConfig
.
BootstrapTokenAuthenticator
=
bootstrap
.
NewTokenAuthenticator
(
versionedInformer
.
Core
()
.
V1
()
.
Secrets
()
.
Lister
()
.
Secrets
(
v1
.
NamespaceSystem
),
versionedInformer
.
Core
()
.
V1
()
.
Secrets
()
.
Lister
()
.
Secrets
(
v1
.
NamespaceSystem
),
...
...
pkg/controller/serviceaccount/tokengetter.go
View file @
a9dc919f
...
@@ -20,30 +20,43 @@ import (
...
@@ -20,30 +20,43 @@ import (
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
clientset
"k8s.io/client-go/kubernetes"
clientset
"k8s.io/client-go/kubernetes"
v1listers
"k8s.io/client-go/listers/core/v1"
"k8s.io/kubernetes/pkg/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"
)
)
// clientGetter implements ServiceAccountTokenGetter using a clientset.Interface
// clientGetter implements ServiceAccountTokenGetter using a clientset.Interface
type
clientGetter
struct
{
type
clientGetter
struct
{
client
clientset
.
Interface
client
clientset
.
Interface
secretLister
v1listers
.
SecretLister
serviceAccountLister
v1listers
.
ServiceAccountLister
podLister
v1listers
.
PodLister
}
}
// NewGetterFromClient returns a ServiceAccountTokenGetter that
// NewGetterFromClient returns a ServiceAccountTokenGetter that
// uses the specified client to retrieve service accounts and secrets.
// uses the specified client to retrieve service accounts and secrets.
// The client should NOT authenticate using a service account token
// The client should NOT authenticate using a service account token
// the returned getter will be used to retrieve, or recursion will result.
// the returned getter will be used to retrieve, or recursion will result.
func
NewGetterFromClient
(
c
clientset
.
Interface
)
serviceaccount
.
ServiceAccountTokenGetter
{
func
NewGetterFromClient
(
c
clientset
.
Interface
,
secretLister
v1listers
.
SecretLister
,
serviceAccountLister
v1listers
.
ServiceAccountLister
,
podLister
v1listers
.
PodLister
)
serviceaccount
.
ServiceAccountTokenGetter
{
return
clientGetter
{
c
}
return
clientGetter
{
c
,
secretLister
,
serviceAccountLister
,
podLister
}
}
}
func
(
c
clientGetter
)
GetServiceAccount
(
namespace
,
name
string
)
(
*
v1
.
ServiceAccount
,
error
)
{
func
(
c
clientGetter
)
GetServiceAccount
(
namespace
,
name
string
)
(
*
v1
.
ServiceAccount
,
error
)
{
if
serviceAccount
,
err
:=
c
.
serviceAccountLister
.
ServiceAccounts
(
namespace
)
.
Get
(
name
);
err
==
nil
{
return
serviceAccount
,
nil
}
return
c
.
client
.
CoreV1
()
.
ServiceAccounts
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
return
c
.
client
.
CoreV1
()
.
ServiceAccounts
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
}
}
func
(
c
clientGetter
)
GetPod
(
namespace
,
name
string
)
(
*
v1
.
Pod
,
error
)
{
func
(
c
clientGetter
)
GetPod
(
namespace
,
name
string
)
(
*
v1
.
Pod
,
error
)
{
if
pod
,
err
:=
c
.
podLister
.
Pods
(
namespace
)
.
Get
(
name
);
err
==
nil
{
return
pod
,
nil
}
return
c
.
client
.
CoreV1
()
.
Pods
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
return
c
.
client
.
CoreV1
()
.
Pods
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
}
}
func
(
c
clientGetter
)
GetSecret
(
namespace
,
name
string
)
(
*
v1
.
Secret
,
error
)
{
func
(
c
clientGetter
)
GetSecret
(
namespace
,
name
string
)
(
*
v1
.
Secret
,
error
)
{
if
secret
,
err
:=
c
.
secretLister
.
Secrets
(
namespace
)
.
Get
(
name
);
err
==
nil
{
return
secret
,
nil
}
return
c
.
client
.
CoreV1
()
.
Secrets
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
return
c
.
client
.
CoreV1
()
.
Secrets
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
}
}
pkg/serviceaccount/BUILD
View file @
a9dc919f
...
@@ -57,6 +57,8 @@ go_test(
...
@@ -57,6 +57,8 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
"//vendor/gopkg.in/square/go-jose.v2/jwt:go_default_library",
"//vendor/gopkg.in/square/go-jose.v2/jwt:go_default_library",
],
],
...
...
pkg/serviceaccount/jwt_test.go
View file @
a9dc919f
...
@@ -19,6 +19,7 @@ package serviceaccount_test
...
@@ -19,6 +19,7 @@ package serviceaccount_test
import
(
import
(
"context"
"context"
"reflect"
"reflect"
"strings"
"testing"
"testing"
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
...
@@ -26,6 +27,8 @@ import (
...
@@ -26,6 +27,8 @@ import (
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/authenticator"
clientset
"k8s.io/client-go/kubernetes"
clientset
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/kubernetes/fake"
v1listers
"k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
certutil
"k8s.io/client-go/util/cert"
certutil
"k8s.io/client-go/util/cert"
serviceaccountcontroller
"k8s.io/kubernetes/pkg/controller/serviceaccount"
serviceaccountcontroller
"k8s.io/kubernetes/pkg/controller/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"
...
@@ -277,7 +280,18 @@ func TestTokenGenerateAndValidate(t *testing.T) {
...
@@ -277,7 +280,18 @@ func TestTokenGenerateAndValidate(t *testing.T) {
for
k
,
tc
:=
range
testCases
{
for
k
,
tc
:=
range
testCases
{
auds
:=
authenticator
.
Audiences
{
"api"
}
auds
:=
authenticator
.
Audiences
{
"api"
}
getter
:=
serviceaccountcontroller
.
NewGetterFromClient
(
tc
.
Client
)
getter
:=
serviceaccountcontroller
.
NewGetterFromClient
(
tc
.
Client
,
v1listers
.
NewSecretLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
tc
.
Client
.
CoreV1
()
.
Secrets
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
v1listers
.
NewServiceAccountLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
tc
.
Client
.
CoreV1
()
.
ServiceAccounts
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
v1listers
.
NewPodLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
tc
.
Client
.
CoreV1
()
.
Pods
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
)
authn
:=
serviceaccount
.
JWTTokenAuthenticator
(
serviceaccount
.
LegacyIssuer
,
tc
.
Keys
,
auds
,
serviceaccount
.
NewLegacyValidator
(
tc
.
Client
!=
nil
,
getter
))
authn
:=
serviceaccount
.
JWTTokenAuthenticator
(
serviceaccount
.
LegacyIssuer
,
tc
.
Keys
,
auds
,
serviceaccount
.
NewLegacyValidator
(
tc
.
Client
!=
nil
,
getter
))
// An invalid, non-JWT token should always fail
// An invalid, non-JWT token should always fail
...
@@ -316,3 +330,23 @@ func TestTokenGenerateAndValidate(t *testing.T) {
...
@@ -316,3 +330,23 @@ func TestTokenGenerateAndValidate(t *testing.T) {
}
}
}
}
}
}
func
newIndexer
(
get
func
(
namespace
,
name
string
)
(
interface
{},
error
))
cache
.
Indexer
{
return
&
fakeIndexer
{
get
:
get
}
}
type
fakeIndexer
struct
{
cache
.
Indexer
get
func
(
namespace
,
name
string
)
(
interface
{},
error
)
}
func
(
f
*
fakeIndexer
)
GetByKey
(
key
string
)
(
interface
{},
bool
,
error
)
{
parts
:=
strings
.
SplitN
(
key
,
"/"
,
2
)
namespace
:=
parts
[
0
]
name
:=
""
if
len
(
parts
)
==
2
{
name
=
parts
[
1
]
}
obj
,
err
:=
f
.
get
(
namespace
,
name
)
return
obj
,
err
==
nil
,
err
}
test/integration/auth/BUILD
View file @
a9dc919f
...
@@ -78,7 +78,9 @@ go_test(
...
@@ -78,7 +78,9 @@ go_test(
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:go_default_library",
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:go_default_library",
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd/api/v1:go_default_library",
"//staging/src/k8s.io/client-go/tools/watch:go_default_library",
"//staging/src/k8s.io/client-go/tools/watch:go_default_library",
"//staging/src/k8s.io/client-go/transport:go_default_library",
"//staging/src/k8s.io/client-go/transport:go_default_library",
...
...
test/integration/auth/svcaccttoken_test.go
View file @
a9dc919f
...
@@ -39,6 +39,8 @@ import (
...
@@ -39,6 +39,8 @@ import (
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeaturetesting
"k8s.io/apiserver/pkg/util/feature/testing"
utilfeaturetesting
"k8s.io/apiserver/pkg/util/feature/testing"
clientset
"k8s.io/client-go/kubernetes"
clientset
"k8s.io/client-go/kubernetes"
v1listers
"k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
certutil
"k8s.io/client-go/util/cert"
certutil
"k8s.io/client-go/util/cert"
"k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core"
serviceaccountgetter
"k8s.io/kubernetes/pkg/controller/serviceaccount"
serviceaccountgetter
"k8s.io/kubernetes/pkg/controller/serviceaccount"
...
@@ -83,7 +85,18 @@ func TestServiceAccountTokenCreate(t *testing.T) {
...
@@ -83,7 +85,18 @@ func TestServiceAccountTokenCreate(t *testing.T) {
iss
,
iss
,
[]
interface
{}{
&
pk
},
[]
interface
{}{
&
pk
},
aud
,
aud
,
serviceaccount
.
NewValidator
(
serviceaccountgetter
.
NewGetterFromClient
(
gcs
)),
serviceaccount
.
NewValidator
(
serviceaccountgetter
.
NewGetterFromClient
(
gcs
,
v1listers
.
NewSecretLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
gcs
.
CoreV1
()
.
Secrets
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
v1listers
.
NewServiceAccountLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
gcs
.
CoreV1
()
.
ServiceAccounts
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
v1listers
.
NewPodLister
(
newIndexer
(
func
(
namespace
,
name
string
)
(
interface
{},
error
)
{
return
gcs
.
CoreV1
()
.
Pods
(
namespace
)
.
Get
(
name
,
metav1
.
GetOptions
{})
})),
)),
),
),
)
)
tokenGenerator
,
err
:=
serviceaccount
.
JWTTokenGenerator
(
iss
,
sk
)
tokenGenerator
,
err
:=
serviceaccount
.
JWTTokenGenerator
(
iss
,
sk
)
...
@@ -683,3 +696,23 @@ func createDeleteSecret(t *testing.T, cs clientset.Interface, sec *v1.Secret) (*
...
@@ -683,3 +696,23 @@ func createDeleteSecret(t *testing.T, cs clientset.Interface, sec *v1.Secret) (*
}
}
}
}
}
}
func
newIndexer
(
get
func
(
namespace
,
name
string
)
(
interface
{},
error
))
cache
.
Indexer
{
return
&
fakeIndexer
{
get
:
get
}
}
type
fakeIndexer
struct
{
cache
.
Indexer
get
func
(
namespace
,
name
string
)
(
interface
{},
error
)
}
func
(
f
*
fakeIndexer
)
GetByKey
(
key
string
)
(
interface
{},
bool
,
error
)
{
parts
:=
strings
.
SplitN
(
key
,
"/"
,
2
)
namespace
:=
parts
[
0
]
name
:=
""
if
len
(
parts
)
==
2
{
name
=
parts
[
1
]
}
obj
,
err
:=
f
.
get
(
namespace
,
name
)
return
obj
,
err
==
nil
,
err
}
test/integration/serviceaccount/service_account_test.go
View file @
a9dc919f
...
@@ -363,6 +363,10 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
...
@@ -363,6 +363,10 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
// TODO: remove rootClient after we refactor pkg/admission to use the clientset.
// TODO: remove rootClient after we refactor pkg/admission to use the clientset.
rootClientset
:=
clientset
.
NewForConfigOrDie
(
&
restclient
.
Config
{
Host
:
apiServer
.
URL
,
ContentConfig
:
restclient
.
ContentConfig
{
GroupVersion
:
&
schema
.
GroupVersion
{
Group
:
""
,
Version
:
"v1"
}},
BearerToken
:
rootToken
})
rootClientset
:=
clientset
.
NewForConfigOrDie
(
&
restclient
.
Config
{
Host
:
apiServer
.
URL
,
ContentConfig
:
restclient
.
ContentConfig
{
GroupVersion
:
&
schema
.
GroupVersion
{
Group
:
""
,
Version
:
"v1"
}},
BearerToken
:
rootToken
})
externalRootClientset
:=
kubernetes
.
NewForConfigOrDie
(
&
restclient
.
Config
{
Host
:
apiServer
.
URL
,
ContentConfig
:
restclient
.
ContentConfig
{
GroupVersion
:
&
schema
.
GroupVersion
{
Group
:
""
,
Version
:
"v1"
}},
BearerToken
:
rootToken
})
externalRootClientset
:=
kubernetes
.
NewForConfigOrDie
(
&
restclient
.
Config
{
Host
:
apiServer
.
URL
,
ContentConfig
:
restclient
.
ContentConfig
{
GroupVersion
:
&
schema
.
GroupVersion
{
Group
:
""
,
Version
:
"v1"
}},
BearerToken
:
rootToken
})
externalInformers
:=
informers
.
NewSharedInformerFactory
(
externalRootClientset
,
controller
.
NoResyncPeriodFunc
())
informers
:=
informers
.
NewSharedInformerFactory
(
rootClientset
,
controller
.
NoResyncPeriodFunc
())
// Set up two authenticators:
// Set up two authenticators:
// 1. A token authenticator that maps the rootToken to the "root" user
// 1. A token authenticator that maps the rootToken to the "root" user
// 2. A ServiceAccountToken authenticator that validates ServiceAccount tokens
// 2. A ServiceAccountToken authenticator that validates ServiceAccount tokens
...
@@ -373,7 +377,12 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
...
@@ -373,7 +377,12 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
return
nil
,
false
,
nil
return
nil
,
false
,
nil
})
})
serviceAccountKey
,
_
:=
rsa
.
GenerateKey
(
rand
.
Reader
,
2048
)
serviceAccountKey
,
_
:=
rsa
.
GenerateKey
(
rand
.
Reader
,
2048
)
serviceAccountTokenGetter
:=
serviceaccountcontroller
.
NewGetterFromClient
(
rootClientset
)
serviceAccountTokenGetter
:=
serviceaccountcontroller
.
NewGetterFromClient
(
rootClientset
,
externalInformers
.
Core
()
.
V1
()
.
Secrets
()
.
Lister
(),
externalInformers
.
Core
()
.
V1
()
.
ServiceAccounts
()
.
Lister
(),
externalInformers
.
Core
()
.
V1
()
.
Pods
()
.
Lister
(),
)
serviceAccountTokenAuth
:=
serviceaccount
.
JWTTokenAuthenticator
(
serviceaccount
.
LegacyIssuer
,
[]
interface
{}{
&
serviceAccountKey
.
PublicKey
},
nil
,
serviceaccount
.
NewLegacyValidator
(
true
,
serviceAccountTokenGetter
))
serviceAccountTokenAuth
:=
serviceaccount
.
JWTTokenAuthenticator
(
serviceaccount
.
LegacyIssuer
,
[]
interface
{}{
&
serviceAccountKey
.
PublicKey
},
nil
,
serviceaccount
.
NewLegacyValidator
(
true
,
serviceAccountTokenGetter
))
authenticator
:=
union
.
New
(
authenticator
:=
union
.
New
(
bearertoken
.
New
(
rootTokenAuth
),
bearertoken
.
New
(
rootTokenAuth
),
...
@@ -418,9 +427,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
...
@@ -418,9 +427,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
// Set up admission plugin to auto-assign serviceaccounts to pods
// Set up admission plugin to auto-assign serviceaccounts to pods
serviceAccountAdmission
:=
serviceaccountadmission
.
NewServiceAccount
()
serviceAccountAdmission
:=
serviceaccountadmission
.
NewServiceAccount
()
serviceAccountAdmission
.
SetExternalKubeClientSet
(
externalRootClientset
)
serviceAccountAdmission
.
SetExternalKubeClientSet
(
externalRootClientset
)
externalInformers
:=
informers
.
NewSharedInformerFactory
(
externalRootClientset
,
controller
.
NoResyncPeriodFunc
())
serviceAccountAdmission
.
SetExternalKubeInformerFactory
(
externalInformers
)
serviceAccountAdmission
.
SetExternalKubeInformerFactory
(
externalInformers
)
informers
:=
informers
.
NewSharedInformerFactory
(
rootClientset
,
controller
.
NoResyncPeriodFunc
())
masterConfig
:=
framework
.
NewMasterConfig
()
masterConfig
:=
framework
.
NewMasterConfig
()
masterConfig
.
GenericConfig
.
EnableIndex
=
true
masterConfig
.
GenericConfig
.
EnableIndex
=
true
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment