mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #26132 from nikhiljindal/newmaster
Automatic merge from submit-queue federation: replacing string credentials field by secretRef Fixes https://github.com/kubernetes/kubernetes/issues/25761 Replaced the string Credentials field in ClusterSpec by secretRef as discussed in https://github.com/kubernetes/kubernetes/issues/25761. Also updated the clusterController to use this new secretRef field while creating a client to talk to a k8s cluster. cc @lavalamp @kubernetes/sig-cluster-federation
This commit is contained in:
commit
4047ca1d97
@ -110,7 +110,15 @@ func DeepCopy_federation_ClusterSpec(in ClusterSpec, out *ClusterSpec, c *conver
|
|||||||
} else {
|
} else {
|
||||||
out.ServerAddressByClientCIDRs = nil
|
out.ServerAddressByClientCIDRs = nil
|
||||||
}
|
}
|
||||||
out.Credential = in.Credential
|
if in.SecretRef != nil {
|
||||||
|
in, out := in.SecretRef, &out.SecretRef
|
||||||
|
*out = new(api.LocalObjectReference)
|
||||||
|
if err := api.DeepCopy_api_LocalObjectReference(*in, *out, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.SecretRef = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg1_api.ConditionStatus
|
var v0 pkg1_api.LocalObjectReference
|
||||||
var v1 pkg3_resource.Quantity
|
var v1 pkg3_resource.Quantity
|
||||||
var v2 pkg2_unversioned.Time
|
var v2 pkg2_unversioned.Time
|
||||||
var v3 pkg4_types.UID
|
var v3 pkg4_types.UID
|
||||||
@ -293,12 +293,11 @@ func (x *ClusterSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
var yyq2 [2]bool
|
var yyq2 [2]bool
|
||||||
_, _, _ = yysep2, yyq2, yy2arr2
|
_, _, _ = yysep2, yyq2, yy2arr2
|
||||||
const yyr2 bool = false
|
const yyr2 bool = false
|
||||||
yyq2[1] = x.Credential != ""
|
|
||||||
var yynn2 int
|
var yynn2 int
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
r.EncodeArrayStart(2)
|
r.EncodeArrayStart(2)
|
||||||
} else {
|
} else {
|
||||||
yynn2 = 1
|
yynn2 = 2
|
||||||
for _, b := range yyq2 {
|
for _, b := range yyq2 {
|
||||||
if b {
|
if b {
|
||||||
yynn2++
|
yynn2++
|
||||||
@ -336,27 +335,19 @@ func (x *ClusterSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
}
|
}
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
|
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if yyq2[1] {
|
if x.SecretRef == nil {
|
||||||
yym7 := z.EncBinary()
|
r.EncodeNil()
|
||||||
_ = yym7
|
|
||||||
if false {
|
|
||||||
} else {
|
|
||||||
r.EncodeString(codecSelferC_UTF81234, string(x.Credential))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
r.EncodeString(codecSelferC_UTF81234, "")
|
x.SecretRef.CodecEncodeSelf(e)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if yyq2[1] {
|
z.EncSendContainerState(codecSelfer_containerMapKey1234)
|
||||||
z.EncSendContainerState(codecSelfer_containerMapKey1234)
|
r.EncodeString(codecSelferC_UTF81234, string("secretRef"))
|
||||||
r.EncodeString(codecSelferC_UTF81234, string("credential"))
|
z.EncSendContainerState(codecSelfer_containerMapValue1234)
|
||||||
z.EncSendContainerState(codecSelfer_containerMapValue1234)
|
if x.SecretRef == nil {
|
||||||
yym8 := z.EncBinary()
|
r.EncodeNil()
|
||||||
_ = yym8
|
} else {
|
||||||
if false {
|
x.SecretRef.CodecEncodeSelf(e)
|
||||||
} else {
|
|
||||||
r.EncodeString(codecSelferC_UTF81234, string(x.Credential))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
@ -432,11 +423,16 @@ func (x *ClusterSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
h.decSliceServerAddressByClientCIDR((*[]ServerAddressByClientCIDR)(yyv4), d)
|
h.decSliceServerAddressByClientCIDR((*[]ServerAddressByClientCIDR)(yyv4), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "credential":
|
case "secretRef":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Credential = ""
|
if x.SecretRef != nil {
|
||||||
|
x.SecretRef = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x.Credential = string(r.DecodeString())
|
if x.SecretRef == nil {
|
||||||
|
x.SecretRef = new(pkg1_api.LocalObjectReference)
|
||||||
|
}
|
||||||
|
x.SecretRef.CodecDecodeSelf(d)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.DecStructFieldNotFound(-1, yys3)
|
z.DecStructFieldNotFound(-1, yys3)
|
||||||
@ -486,9 +482,14 @@ func (x *ClusterSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Credential = ""
|
if x.SecretRef != nil {
|
||||||
|
x.SecretRef = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x.Credential = string(r.DecodeString())
|
if x.SecretRef == nil {
|
||||||
|
x.SecretRef = new(pkg1_api.LocalObjectReference)
|
||||||
|
}
|
||||||
|
x.SecretRef.CodecDecodeSelf(d)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
yyj7++
|
yyj7++
|
||||||
@ -2447,7 +2448,7 @@ func (x codecSelfer1234) decSliceCluster(v *[]Cluster, d *codec1978.Decoder) {
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 336)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 328)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
|
@ -37,10 +37,11 @@ type ClusterSpec struct {
|
|||||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" patchStrategy:"merge" patchMergeKey:"clientCIDR"`
|
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" patchStrategy:"merge" patchMergeKey:"clientCIDR"`
|
||||||
// the type (e.g. bearer token, client certificate etc) and data of the credential used to access cluster.
|
// Name of the secret containing kubeconfig to access this cluster.
|
||||||
// It’s used for system routines (not behalf of users)
|
// The secret is read from the kubernetes cluster that is hosting federation control plane.
|
||||||
// TODO: string may not enough, https://github.com/kubernetes/kubernetes/pull/23847#discussion_r59301275
|
// Admin needs to ensure that the required secret exists. Secret should be in the same namespace where federation control plane is hosted and it should have kubeconfig in its data with key "kubeconfig".
|
||||||
Credential string `json:"credential,omitempty"`
|
// This will later be changed to a reference to secret in federation control plane when the federation control plane supports secrets.
|
||||||
|
SecretRef *api.LocalObjectReference `json:"secretRef"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClusterConditionType string
|
type ClusterConditionType string
|
||||||
|
@ -208,7 +208,16 @@ func autoConvert_v1alpha1_ClusterSpec_To_federation_ClusterSpec(in *ClusterSpec,
|
|||||||
} else {
|
} else {
|
||||||
out.ServerAddressByClientCIDRs = nil
|
out.ServerAddressByClientCIDRs = nil
|
||||||
}
|
}
|
||||||
out.Credential = in.Credential
|
if in.SecretRef != nil {
|
||||||
|
in, out := &in.SecretRef, &out.SecretRef
|
||||||
|
*out = new(api.LocalObjectReference)
|
||||||
|
// TODO: Inefficient conversion - can we improve it?
|
||||||
|
if err := s.Convert(*in, *out, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.SecretRef = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +237,16 @@ func autoConvert_federation_ClusterSpec_To_v1alpha1_ClusterSpec(in *federation.C
|
|||||||
} else {
|
} else {
|
||||||
out.ServerAddressByClientCIDRs = nil
|
out.ServerAddressByClientCIDRs = nil
|
||||||
}
|
}
|
||||||
out.Credential = in.Credential
|
if in.SecretRef != nil {
|
||||||
|
in, out := &in.SecretRef, &out.SecretRef
|
||||||
|
*out = new(v1.LocalObjectReference)
|
||||||
|
// TODO: Inefficient conversion - can we improve it?
|
||||||
|
if err := s.Convert(*in, *out, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.SecretRef = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,15 @@ func DeepCopy_v1alpha1_ClusterSpec(in ClusterSpec, out *ClusterSpec, c *conversi
|
|||||||
} else {
|
} else {
|
||||||
out.ServerAddressByClientCIDRs = nil
|
out.ServerAddressByClientCIDRs = nil
|
||||||
}
|
}
|
||||||
out.Credential = in.Credential
|
if in.SecretRef != nil {
|
||||||
|
in, out := in.SecretRef, &out.SecretRef
|
||||||
|
*out = new(v1.LocalObjectReference)
|
||||||
|
if err := v1.DeepCopy_v1_LocalObjectReference(*in, *out, c); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.SecretRef = nil
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,10 +266,16 @@ func (m *ClusterSpec) MarshalTo(data []byte) (int, error) {
|
|||||||
i += n
|
i += n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data[i] = 0x12
|
if m.SecretRef != nil {
|
||||||
i++
|
data[i] = 0x12
|
||||||
i = encodeVarintGenerated(data, i, uint64(len(m.Credential)))
|
i++
|
||||||
i += copy(data[i:], m.Credential)
|
i = encodeVarintGenerated(data, i, uint64(m.SecretRef.Size()))
|
||||||
|
n7, err := m.SecretRef.MarshalTo(data[i:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
i += n7
|
||||||
|
}
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,11 +321,11 @@ func (m *ClusterStatus) MarshalTo(data []byte) (int, error) {
|
|||||||
data[i] = 0x12
|
data[i] = 0x12
|
||||||
i++
|
i++
|
||||||
i = encodeVarintGenerated(data, i, uint64((&v).Size()))
|
i = encodeVarintGenerated(data, i, uint64((&v).Size()))
|
||||||
n7, err := (&v).MarshalTo(data[i:])
|
n8, err := (&v).MarshalTo(data[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n7
|
i += n8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(m.Allocatable) > 0 {
|
if len(m.Allocatable) > 0 {
|
||||||
@ -337,21 +343,21 @@ func (m *ClusterStatus) MarshalTo(data []byte) (int, error) {
|
|||||||
data[i] = 0x12
|
data[i] = 0x12
|
||||||
i++
|
i++
|
||||||
i = encodeVarintGenerated(data, i, uint64((&v).Size()))
|
i = encodeVarintGenerated(data, i, uint64((&v).Size()))
|
||||||
n8, err := (&v).MarshalTo(data[i:])
|
n9, err := (&v).MarshalTo(data[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n8
|
i += n9
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data[i] = 0x22
|
data[i] = 0x22
|
||||||
i++
|
i++
|
||||||
i = encodeVarintGenerated(data, i, uint64(m.ClusterMeta.Size()))
|
i = encodeVarintGenerated(data, i, uint64(m.ClusterMeta.Size()))
|
||||||
n9, err := m.ClusterMeta.MarshalTo(data[i:])
|
n10, err := m.ClusterMeta.MarshalTo(data[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
i += n9
|
i += n10
|
||||||
return i, nil
|
return i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,8 +475,10 @@ func (m *ClusterSpec) Size() (n int) {
|
|||||||
n += 1 + l + sovGenerated(uint64(l))
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l = len(m.Credential)
|
if m.SecretRef != nil {
|
||||||
n += 1 + l + sovGenerated(uint64(l))
|
l = m.SecretRef.Size()
|
||||||
|
n += 1 + l + sovGenerated(uint64(l))
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,9 +1155,9 @@ func (m *ClusterSpec) Unmarshal(data []byte) error {
|
|||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
case 2:
|
case 2:
|
||||||
if wireType != 2 {
|
if wireType != 2 {
|
||||||
return fmt.Errorf("proto: wrong wireType = %d for field Credential", wireType)
|
return fmt.Errorf("proto: wrong wireType = %d for field SecretRef", wireType)
|
||||||
}
|
}
|
||||||
var stringLen uint64
|
var msglen int
|
||||||
for shift := uint(0); ; shift += 7 {
|
for shift := uint(0); ; shift += 7 {
|
||||||
if shift >= 64 {
|
if shift >= 64 {
|
||||||
return ErrIntOverflowGenerated
|
return ErrIntOverflowGenerated
|
||||||
@ -1159,20 +1167,24 @@ func (m *ClusterSpec) Unmarshal(data []byte) error {
|
|||||||
}
|
}
|
||||||
b := data[iNdEx]
|
b := data[iNdEx]
|
||||||
iNdEx++
|
iNdEx++
|
||||||
stringLen |= (uint64(b) & 0x7F) << shift
|
msglen |= (int(b) & 0x7F) << shift
|
||||||
if b < 0x80 {
|
if b < 0x80 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
intStringLen := int(stringLen)
|
if msglen < 0 {
|
||||||
if intStringLen < 0 {
|
|
||||||
return ErrInvalidLengthGenerated
|
return ErrInvalidLengthGenerated
|
||||||
}
|
}
|
||||||
postIndex := iNdEx + intStringLen
|
postIndex := iNdEx + msglen
|
||||||
if postIndex > l {
|
if postIndex > l {
|
||||||
return io.ErrUnexpectedEOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
m.Credential = string(data[iNdEx:postIndex])
|
if m.SecretRef == nil {
|
||||||
|
m.SecretRef = &k8s_io_kubernetes_pkg_api_v1.LocalObjectReference{}
|
||||||
|
}
|
||||||
|
if err := m.SecretRef.Unmarshal(data[iNdEx:postIndex]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
|
@ -87,10 +87,11 @@ message ClusterSpec {
|
|||||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||||
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 1;
|
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 1;
|
||||||
|
|
||||||
// the type (e.g. bearer token, client certificate etc) and data of the credential used to access cluster.
|
// Name of the secret containing kubeconfig to access this cluster.
|
||||||
// It’s used for system routines (not behalf of users)
|
// The secret is read from the kubernetes cluster that is hosting federation control plane.
|
||||||
// TODO: string may not enough, https://github.com/kubernetes/kubernetes/pull/23847#discussion_r59301275
|
// Admin needs to ensure that the required secret exists. Secret should be in the same namespace where federation control plane is hosted and it should have kubeconfig in its data with key "kubeconfig".
|
||||||
optional string credential = 2;
|
// This will later be changed to a reference to secret in federation control plane when the federation control plane supports secrets.
|
||||||
|
optional k8s.io.kubernetes.pkg.api.v1.LocalObjectReference secretRef = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClusterStatus is information about the current status of a cluster updated by cluster controller peridocally.
|
// ClusterStatus is information about the current status of a cluster updated by cluster controller peridocally.
|
||||||
|
@ -66,7 +66,7 @@ func init() {
|
|||||||
if false { // reference the types, but skip this branch at build/run time
|
if false { // reference the types, but skip this branch at build/run time
|
||||||
var v0 pkg3_resource.Quantity
|
var v0 pkg3_resource.Quantity
|
||||||
var v1 pkg2_unversioned.Time
|
var v1 pkg2_unversioned.Time
|
||||||
var v2 pkg1_v1.ConditionStatus
|
var v2 pkg1_v1.LocalObjectReference
|
||||||
var v3 pkg4_types.UID
|
var v3 pkg4_types.UID
|
||||||
var v4 time.Time
|
var v4 time.Time
|
||||||
_, _, _, _, _ = v0, v1, v2, v3, v4
|
_, _, _, _, _ = v0, v1, v2, v3, v4
|
||||||
@ -293,12 +293,11 @@ func (x *ClusterSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
var yyq2 [2]bool
|
var yyq2 [2]bool
|
||||||
_, _, _ = yysep2, yyq2, yy2arr2
|
_, _, _ = yysep2, yyq2, yy2arr2
|
||||||
const yyr2 bool = false
|
const yyr2 bool = false
|
||||||
yyq2[1] = x.Credential != ""
|
|
||||||
var yynn2 int
|
var yynn2 int
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
r.EncodeArrayStart(2)
|
r.EncodeArrayStart(2)
|
||||||
} else {
|
} else {
|
||||||
yynn2 = 1
|
yynn2 = 2
|
||||||
for _, b := range yyq2 {
|
for _, b := range yyq2 {
|
||||||
if b {
|
if b {
|
||||||
yynn2++
|
yynn2++
|
||||||
@ -336,27 +335,19 @@ func (x *ClusterSpec) CodecEncodeSelf(e *codec1978.Encoder) {
|
|||||||
}
|
}
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
|
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if yyq2[1] {
|
if x.SecretRef == nil {
|
||||||
yym7 := z.EncBinary()
|
r.EncodeNil()
|
||||||
_ = yym7
|
|
||||||
if false {
|
|
||||||
} else {
|
|
||||||
r.EncodeString(codecSelferC_UTF81234, string(x.Credential))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
r.EncodeString(codecSelferC_UTF81234, "")
|
x.SecretRef.CodecEncodeSelf(e)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if yyq2[1] {
|
z.EncSendContainerState(codecSelfer_containerMapKey1234)
|
||||||
z.EncSendContainerState(codecSelfer_containerMapKey1234)
|
r.EncodeString(codecSelferC_UTF81234, string("secretRef"))
|
||||||
r.EncodeString(codecSelferC_UTF81234, string("credential"))
|
z.EncSendContainerState(codecSelfer_containerMapValue1234)
|
||||||
z.EncSendContainerState(codecSelfer_containerMapValue1234)
|
if x.SecretRef == nil {
|
||||||
yym8 := z.EncBinary()
|
r.EncodeNil()
|
||||||
_ = yym8
|
} else {
|
||||||
if false {
|
x.SecretRef.CodecEncodeSelf(e)
|
||||||
} else {
|
|
||||||
r.EncodeString(codecSelferC_UTF81234, string(x.Credential))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if yyr2 || yy2arr2 {
|
if yyr2 || yy2arr2 {
|
||||||
@ -432,11 +423,16 @@ func (x *ClusterSpec) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
|
|||||||
h.decSliceServerAddressByClientCIDR((*[]ServerAddressByClientCIDR)(yyv4), d)
|
h.decSliceServerAddressByClientCIDR((*[]ServerAddressByClientCIDR)(yyv4), d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "credential":
|
case "secretRef":
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Credential = ""
|
if x.SecretRef != nil {
|
||||||
|
x.SecretRef = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x.Credential = string(r.DecodeString())
|
if x.SecretRef == nil {
|
||||||
|
x.SecretRef = new(pkg1_v1.LocalObjectReference)
|
||||||
|
}
|
||||||
|
x.SecretRef.CodecDecodeSelf(d)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
z.DecStructFieldNotFound(-1, yys3)
|
z.DecStructFieldNotFound(-1, yys3)
|
||||||
@ -486,9 +482,14 @@ func (x *ClusterSpec) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
|
|||||||
}
|
}
|
||||||
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
|
||||||
if r.TryDecodeAsNil() {
|
if r.TryDecodeAsNil() {
|
||||||
x.Credential = ""
|
if x.SecretRef != nil {
|
||||||
|
x.SecretRef = nil
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x.Credential = string(r.DecodeString())
|
if x.SecretRef == nil {
|
||||||
|
x.SecretRef = new(pkg1_v1.LocalObjectReference)
|
||||||
|
}
|
||||||
|
x.SecretRef.CodecDecodeSelf(d)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
yyj7++
|
yyj7++
|
||||||
@ -2447,7 +2448,7 @@ func (x codecSelfer1234) decSliceCluster(v *[]Cluster, d *codec1978.Decoder) {
|
|||||||
|
|
||||||
yyrg1 := len(yyv1) > 0
|
yyrg1 := len(yyv1) > 0
|
||||||
yyv21 := yyv1
|
yyv21 := yyv1
|
||||||
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 336)
|
yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 328)
|
||||||
if yyrt1 {
|
if yyrt1 {
|
||||||
if yyrl1 <= cap(yyv1) {
|
if yyrl1 <= cap(yyv1) {
|
||||||
yyv1 = yyv1[:yyrl1]
|
yyv1 = yyv1[:yyrl1]
|
||||||
|
@ -37,10 +37,11 @@ type ClusterSpec struct {
|
|||||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" patchStrategy:"merge" patchMergeKey:"clientCIDR" protobuf:"bytes,1,rep,name=serverAddressByClientCIDRs"`
|
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" patchStrategy:"merge" patchMergeKey:"clientCIDR" protobuf:"bytes,1,rep,name=serverAddressByClientCIDRs"`
|
||||||
// the type (e.g. bearer token, client certificate etc) and data of the credential used to access cluster.
|
// Name of the secret containing kubeconfig to access this cluster.
|
||||||
// It’s used for system routines (not behalf of users)
|
// The secret is read from the kubernetes cluster that is hosting federation control plane.
|
||||||
// TODO: string may not enough, https://github.com/kubernetes/kubernetes/pull/23847#discussion_r59301275
|
// Admin needs to ensure that the required secret exists. Secret should be in the same namespace where federation control plane is hosted and it should have kubeconfig in its data with key "kubeconfig".
|
||||||
Credential string `json:"credential,omitempty" protobuf:"bytes,2,opt,name=credential"`
|
// This will later be changed to a reference to secret in federation control plane when the federation control plane supports secrets.
|
||||||
|
SecretRef *v1.LocalObjectReference `json:"secretRef" protobuf:"bytes,2,opt,name=secretRef"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClusterConditionType string
|
type ClusterConditionType string
|
||||||
|
@ -17,7 +17,9 @@ limitations under the License.
|
|||||||
package cluster
|
package cluster
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
federation_v1alpha1 "k8s.io/kubernetes/federation/apis/federation/v1alpha1"
|
federation_v1alpha1 "k8s.io/kubernetes/federation/apis/federation/v1alpha1"
|
||||||
@ -25,16 +27,45 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||||
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UserAgentName = "Cluster-Controller"
|
UserAgentName = "Cluster-Controller"
|
||||||
KubeAPIQPS = 20.0
|
KubeAPIQPS = 20.0
|
||||||
KubeAPIBurst = 30
|
KubeAPIBurst = 30
|
||||||
|
KubeconfigSecretDataKey = "kubeconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// This is to inject a different kubeconfigGetter in tests.
|
||||||
|
// We dont use the standard one which calls NewInCluster in tests to avoid having to setup service accounts and mount files with secret tokens.
|
||||||
|
var KubeconfigGetterForCluster = func(c *federation_v1alpha1.Cluster) clientcmd.KubeconfigGetter {
|
||||||
|
return func() (*clientcmdapi.Config, error) {
|
||||||
|
// Get the namespace this is running in from the env variable.
|
||||||
|
namespace := os.Getenv("POD_NAMESPACE")
|
||||||
|
if namespace == "" {
|
||||||
|
return nil, fmt.Errorf("unexpected: POD_NAMESPACE env var returned empty string")
|
||||||
|
}
|
||||||
|
// Get a client to talk to the k8s apiserver, to fetch secrets from it.
|
||||||
|
client, err := client.NewInCluster()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error in creating in-cluster client: %s", err)
|
||||||
|
}
|
||||||
|
secret, err := client.Secrets(namespace).Get(c.Spec.SecretRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error in fetching secret: %s", err)
|
||||||
|
}
|
||||||
|
data, ok := secret.Data[KubeconfigSecretDataKey]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("secret does not have data with key: %s", KubeconfigSecretDataKey)
|
||||||
|
}
|
||||||
|
return clientcmd.Load(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ClusterClient struct {
|
type ClusterClient struct {
|
||||||
discoveryClient *discovery.DiscoveryClient
|
discoveryClient *discovery.DiscoveryClient
|
||||||
}
|
}
|
||||||
@ -59,7 +90,8 @@ func NewClusterClientSet(c *federation_v1alpha1.Cluster) (*ClusterClient, error)
|
|||||||
}
|
}
|
||||||
var clusterClientSet = ClusterClient{}
|
var clusterClientSet = ClusterClient{}
|
||||||
if serverAddress != "" {
|
if serverAddress != "" {
|
||||||
clusterConfig, err := clientcmd.BuildConfigFromFlags(serverAddress, "")
|
kubeconfigGetter := KubeconfigGetterForCluster(c)
|
||||||
|
clusterConfig, err := clientcmd.BuildConfigFromKubeconfigGetter(serverAddress, kubeconfigGetter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
"k8s.io/kubernetes/pkg/util"
|
"k8s.io/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -122,6 +123,14 @@ func TestUpdateClusterStatusOK(t *testing.T) {
|
|||||||
}
|
}
|
||||||
federationClientSet := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, "cluster-controller"))
|
federationClientSet := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, "cluster-controller"))
|
||||||
|
|
||||||
|
// Override KubeconfigGetterForCluster to avoid having to setup service accounts and mount files with secret tokens.
|
||||||
|
originalGetter := KubeconfigGetterForCluster
|
||||||
|
KubeconfigGetterForCluster = func(c *federation_v1alpha1.Cluster) clientcmd.KubeconfigGetter {
|
||||||
|
return func() (*clientcmdapi.Config, error) {
|
||||||
|
return &clientcmdapi.Config{}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
manager := NewclusterController(federationClientSet, 5)
|
manager := NewclusterController(federationClientSet, 5)
|
||||||
err = manager.UpdateClusterStatus()
|
err = manager.UpdateClusterStatus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -135,4 +144,7 @@ func TestUpdateClusterStatusOK(t *testing.T) {
|
|||||||
t.Errorf("Failed to Update Cluster Status")
|
t.Errorf("Failed to Update Cluster Status")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset KubeconfigGetterForCluster
|
||||||
|
KubeconfigGetterForCluster = originalGetter
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,9 @@ func TestUpdate(t *testing.T) {
|
|||||||
// updateFunc
|
// updateFunc
|
||||||
func(obj runtime.Object) runtime.Object {
|
func(obj runtime.Object) runtime.Object {
|
||||||
object := obj.(*federation.Cluster)
|
object := obj.(*federation.Cluster)
|
||||||
object.Spec.Credential = "bar"
|
object.Spec.SecretRef = &api.LocalObjectReference{
|
||||||
|
Name: "bar",
|
||||||
|
}
|
||||||
return object
|
return object
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -54,14 +54,12 @@ func validNewCluster() *federation.Cluster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func invalidNewCluster() *federation.Cluster {
|
func invalidNewCluster() *federation.Cluster {
|
||||||
|
// Create a cluster with empty ServerAddressByClientCIDRs (which is a required field).
|
||||||
return &federation.Cluster{
|
return &federation.Cluster{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: "foo2",
|
Name: "foo2",
|
||||||
ResourceVersion: "5",
|
ResourceVersion: "5",
|
||||||
},
|
},
|
||||||
Spec: federation.ClusterSpec{
|
|
||||||
Credential: "bar",
|
|
||||||
},
|
|
||||||
Status: federation.ClusterStatus{
|
Status: federation.ClusterStatus{
|
||||||
Conditions: []federation.ClusterCondition{
|
Conditions: []federation.ClusterCondition{
|
||||||
{Type: federation.ClusterReady, Status: api.ConditionFalse},
|
{Type: federation.ClusterReady, Status: api.ConditionFalse},
|
||||||
|
@ -399,3 +399,13 @@ func BuildConfigFromFlags(masterUrl, kubeconfigPath string) (*restclient.Config,
|
|||||||
&ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
|
&ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
|
||||||
&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
|
&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}}).ClientConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildConfigFromKubeconfigGetter is a helper function that builds configs from a master
|
||||||
|
// url and a kubeconfigGetter.
|
||||||
|
func BuildConfigFromKubeconfigGetter(masterUrl string, kubeconfigGetter KubeconfigGetter) (*restclient.Config, error) {
|
||||||
|
// TODO: We do not need a DeferredLoader here. Refactor code and see if we can use DirectClientConfig here.
|
||||||
|
cc := NewNonInteractiveDeferredLoadingClientConfig(
|
||||||
|
&ClientConfigGetter{kubeconfigGetter: kubeconfigGetter},
|
||||||
|
&ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: masterUrl}})
|
||||||
|
return cc.ClientConfig()
|
||||||
|
}
|
||||||
|
@ -63,6 +63,40 @@ func currentMigrationRules() map[string]string {
|
|||||||
return migrationRules
|
return migrationRules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ClientConfigLoader interface {
|
||||||
|
ConfigAccess
|
||||||
|
Load() (*clientcmdapi.Config, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type KubeconfigGetter func() (*clientcmdapi.Config, error)
|
||||||
|
|
||||||
|
type ClientConfigGetter struct {
|
||||||
|
kubeconfigGetter KubeconfigGetter
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientConfigGetter implements the ClientConfigLoader interface.
|
||||||
|
var _ ClientConfigLoader = &ClientConfigGetter{}
|
||||||
|
|
||||||
|
func (g *ClientConfigGetter) Load() (*clientcmdapi.Config, error) {
|
||||||
|
return g.kubeconfigGetter()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *ClientConfigGetter) GetLoadingPrecedence() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (g *ClientConfigGetter) GetStartingConfig() (*clientcmdapi.Config, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
func (g *ClientConfigGetter) GetDefaultFilename() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
func (g *ClientConfigGetter) IsExplicitFile() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func (g *ClientConfigGetter) GetExplicitFile() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config
|
// ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config
|
||||||
// Callers can put the chain together however they want, but we'd recommend:
|
// Callers can put the chain together however they want, but we'd recommend:
|
||||||
// EnvVarPathFiles if set (a list of files if set) OR the HomeDirectoryPath
|
// EnvVarPathFiles if set (a list of files if set) OR the HomeDirectoryPath
|
||||||
@ -80,6 +114,9 @@ type ClientConfigLoadingRules struct {
|
|||||||
DoNotResolvePaths bool
|
DoNotResolvePaths bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClientConfigLoadingRules implements the ClientConfigLoader interface.
|
||||||
|
var _ ClientConfigLoader = &ClientConfigLoadingRules{}
|
||||||
|
|
||||||
// NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to
|
// NewDefaultClientConfigLoadingRules returns a ClientConfigLoadingRules object with default fields filled in. You are not required to
|
||||||
// use this constructor
|
// use this constructor
|
||||||
func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules {
|
func NewDefaultClientConfigLoadingRules() *ClientConfigLoadingRules {
|
||||||
|
@ -27,13 +27,13 @@ import (
|
|||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a set of loading rules
|
// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a client config loader.
|
||||||
// It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that
|
// It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that
|
||||||
// the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before
|
// the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before
|
||||||
// the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid
|
// the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid
|
||||||
// passing extraneous information down a call stack
|
// passing extraneous information down a call stack
|
||||||
type DeferredLoadingClientConfig struct {
|
type DeferredLoadingClientConfig struct {
|
||||||
loadingRules *ClientConfigLoadingRules
|
loader ClientConfigLoader
|
||||||
overrides *ConfigOverrides
|
overrides *ConfigOverrides
|
||||||
fallbackReader io.Reader
|
fallbackReader io.Reader
|
||||||
|
|
||||||
@ -42,13 +42,13 @@ type DeferredLoadingClientConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
|
// NewNonInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name
|
||||||
func NewNonInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides) ClientConfig {
|
func NewNonInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides) ClientConfig {
|
||||||
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides}
|
return &DeferredLoadingClientConfig{loader: loader, overrides: overrides}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
|
// NewInteractiveDeferredLoadingClientConfig creates a ConfigClientClientConfig using the passed context name and the fallback auth reader
|
||||||
func NewInteractiveDeferredLoadingClientConfig(loadingRules *ClientConfigLoadingRules, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
func NewInteractiveDeferredLoadingClientConfig(loader ClientConfigLoader, overrides *ConfigOverrides, fallbackReader io.Reader) ClientConfig {
|
||||||
return &DeferredLoadingClientConfig{loadingRules: loadingRules, overrides: overrides, fallbackReader: fallbackReader}
|
return &DeferredLoadingClientConfig{loader: loader, overrides: overrides, fallbackReader: fallbackReader}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
|
func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, error) {
|
||||||
@ -57,16 +57,16 @@ func (config *DeferredLoadingClientConfig) createClientConfig() (ClientConfig, e
|
|||||||
defer config.loadingLock.Unlock()
|
defer config.loadingLock.Unlock()
|
||||||
|
|
||||||
if config.clientConfig == nil {
|
if config.clientConfig == nil {
|
||||||
mergedConfig, err := config.loadingRules.Load()
|
mergedConfig, err := config.loader.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var mergedClientConfig ClientConfig
|
var mergedClientConfig ClientConfig
|
||||||
if config.fallbackReader != nil {
|
if config.fallbackReader != nil {
|
||||||
mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loadingRules)
|
mergedClientConfig = NewInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.fallbackReader, config.loader)
|
||||||
} else {
|
} else {
|
||||||
mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loadingRules)
|
mergedClientConfig = NewNonInteractiveClientConfig(*mergedConfig, config.overrides.CurrentContext, config.overrides, config.loader)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.clientConfig = mergedClientConfig
|
config.clientConfig = mergedClientConfig
|
||||||
@ -118,5 +118,5 @@ func (config *DeferredLoadingClientConfig) Namespace() (string, bool, error) {
|
|||||||
|
|
||||||
// ConfigAccess implements ClientConfig
|
// ConfigAccess implements ClientConfig
|
||||||
func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess {
|
func (config *DeferredLoadingClientConfig) ConfigAccess() ConfigAccess {
|
||||||
return config.loadingRules
|
return config.loader
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user