1
0
mirror of https://github.com/rancher/types.git synced 2025-08-01 04:57:05 +00:00

Add secret types

This commit is contained in:
Darren Shepherd 2017-12-22 23:26:07 -07:00
parent c695ca2ba6
commit 0545d29b2b
8 changed files with 563 additions and 4 deletions

View File

@ -0,0 +1,100 @@
package schema
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/mapper"
"k8s.io/api/core/v1"
)
type EndpointAddressMapper struct {
}
func (e EndpointAddressMapper) FromInternal(data map[string]interface{}) {
if data == nil {
return
}
var subsets []v1.EndpointSubset
if err := convert.ToObj(data["subsets"], &subsets); err != nil {
log.Errorf("Failed to convert subset: %v", err)
return
}
var noPortsIPs []string
var result []interface{}
for _, subset := range subsets {
var ips []string
for _, ip := range subset.Addresses {
if ip.IP != "" {
ips = append(ips, ip.IP)
}
if ip.Hostname != "" {
ips = append(ips, ip.Hostname)
}
}
if len(ips) == 0 {
noPortsIPs = append(noPortsIPs, ips...)
} else {
for _, port := range subset.Ports {
if len(ips) > 0 {
result = append(result, map[string]interface{}{
"addresses": ips,
"port": port.Port,
"protocol": port.Protocol,
})
}
}
}
}
if len(noPortsIPs) > 0 {
result = append(result, map[string]interface{}{
"addresses": noPortsIPs,
})
}
if len(result) > 0 {
data["targets"] = result
}
}
func (e EndpointAddressMapper) ToInternal(data map[string]interface{}) {
if data == nil {
return
}
var addresses []Target
var subsets []v1.EndpointSubset
if err := convert.ToObj(data["targets"], &addresses); err != nil {
log.Errorf("Failed to convert addresses: %v", err)
return
}
for _, address := range addresses {
subset := v1.EndpointSubset{}
for _, ip := range address.Addresses {
subset.Addresses = append(subset.Addresses, v1.EndpointAddress{
IP: ip,
})
}
if address.Port != nil {
subset.Ports = append(subset.Ports, v1.EndpointPort{
Port: *address.Port,
Protocol: v1.Protocol(address.Protocol),
})
}
subsets = append(subsets, subset)
}
if len(subsets) > 0 {
data["subsets"] = subsets
}
}
func (e EndpointAddressMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
mapper.ValidateField("subsets", schema)
delete(schema.ResourceFields, "subsets")
return nil
}

View File

@ -0,0 +1,7 @@
package schema
import "github.com/sirupsen/logrus"
var (
log = logrus.WithField("component", "types/mapper")
)

View File

@ -0,0 +1,32 @@
package schema
import (
"encoding/base64"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
type RegistryCredentialMapper struct {
}
func (e RegistryCredentialMapper) FromInternal(data map[string]interface{}) {
}
func (e RegistryCredentialMapper) ToInternal(data map[string]interface{}) {
if data == nil {
return
}
auth := convert.ToString(data["auth"])
username := convert.ToString(data["username"])
password := convert.ToString(data["password"])
if auth == "" && username != "" && password != "" {
data["auth"] = base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
}
}
func (e RegistryCredentialMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@ -22,6 +22,8 @@ var (
Schemas = factory.Schemas(&Version).
// Namespace must be first
Init(secretTypes).
Init(serviceTypes).
Init(namespaceTypes).
Init(podTypes).
Init(deploymentTypes).
@ -84,19 +86,19 @@ func statefulSetTypes(schemas *types.Schemas) *types.Schemas {
To: "deploymentStrategy/orderedConfig/partition",
},
m.SetValue{
From: "updateStrategy/type",
Field: "updateStrategy/type",
IfEq: "OnDelete",
Value: true,
To: "deploymentStrategy/orderedConfig/onDelete",
},
m.SetValue{
From: "podManagementPolicy",
Field: "podManagementPolicy",
IfEq: "Parallel",
Value: "Parallel",
To: "deploymentStrategy/kind",
},
m.SetValue{
From: "podManagementPolicy",
Field: "podManagementPolicy",
IfEq: "OrderedReady",
Value: "Ordered",
To: "deploymentStrategy/kind",
@ -157,7 +159,7 @@ func daemonSet(schemas *types.Schemas) *types.Schemas {
return schemas.
AddMapperForType(&Version, v1beta2.DaemonSetSpec{},
m.SetValue{
From: "updateStrategy/type",
Field: "updateStrategy/type",
IfEq: "OnDelete",
Value: true,
To: "deploymentStrategy/globalConfig/onDelete",
@ -263,6 +265,7 @@ func podTypes(schemas *types.Schemas) *types.Schemas {
mapper.NamespaceMapper{},
mapper.InitContainerMapper{},
mapper.SchedulingMapper{},
m.Move{From: "tolerations", To: "scheduling/tolerations", DestDefined: true},
&m.Embed{Field: "securityContext"},
&m.Drop{Field: "serviceAccount"},
&m.SliceToMap{
@ -304,3 +307,37 @@ func podTypes(schemas *types.Schemas) *types.Schemas {
WorkloadID string `norman:"type=reference[workload]"`
}{})
}
func serviceTypes(schemas *types.Schemas) *types.Schemas {
return schemas.
TypeName("endpoint", v1.Endpoints{}).
AddMapperForType(&Version, v1.ServiceSpec{},
&m.Move{From: "type", To: "serviceKind"},
&m.Move{From: "externalName", To: "hostname"},
&m.Move{From: "clusterIP", To: "clusterIp"},
ServiceKindMapper{},
).
AddMapperForType(&Version, v1.Service{},
&m.LabelField{Field: "workloadId"},
&m.Drop{Field: "status"},
&m.Move{From: "serviceKind", To: "kind"},
&mapper.NamespaceIDMapper{},
&m.AnnotationField{Field: "targetWorkloadIds", Object: true},
&m.AnnotationField{Field: "targetServiceIds", Object: true},
).
AddMapperForType(&Version, v1.Endpoints{},
&EndpointAddressMapper{},
&mapper.NamespaceIDMapper{},
).
MustImport(&Version, v1.Service{}, projectOverride{}, struct {
WorkloadID string `json:"workloadId" norman:"type=reference[workload]"`
TargetWorkloadIDs string `json:"targetWorkloadIds" norman:"type=array[reference[workload]]"`
TargetServiceIDs string `json:"targetServiceIds" norman:"type=array[reference[service]]"`
Kind string `json:"kind" norman:"type=enum,options=Alias|ARecord|CName|ClusterIP|NodeIP|LoadBalancer"`
}{}).
MustImportAndCustomize(&Version, v1.Endpoints{}, func(schema *types.Schema) {
schema.CodeName = "Endpoint"
}, projectOverride{}, struct {
Targets []Target `json:"targets"`
}{})
}

View File

@ -0,0 +1,255 @@
package schema
import (
"github.com/rancher/norman/types"
m "github.com/rancher/norman/types/mapper"
"github.com/rancher/types/apis/project.cattle.io/v3"
"github.com/rancher/types/mapper"
"k8s.io/api/core/v1"
)
func secretTypes(schemas *types.Schemas) *types.Schemas {
return schemas.
AddMapperForType(&Version, v1.Secret{},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/service-account-token",
Value: "serviceAccountToken",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/dockercfg",
Value: "dockerCredential",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/dockerconfigjson",
Value: "dockerCredential",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/basic-auth",
Value: "basicAuth",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/ssh-auth",
Value: "sshAuth",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/ssh-auth",
Value: "sshAuth",
},
m.SetValue{
Field: "type",
To: "type",
IfEq: "kubernetes.io/tls",
Value: "certificate",
},
&m.Move{From: "type", To: "kind"},
&mapper.NamespaceIDMapper{},
m.Condition{
Field: "kind",
Value: "sshAuth",
Mapper: types.Mappers{
m.UntypedMove{
From: "data/ssh-privatekey",
To: "privateKey",
},
m.Base64{
Field: "privateKey",
IgnoreDefinition: true,
},
m.SetValue{
Field: "type",
Value: "sshAuth",
IgnoreDefinition: true,
},
},
},
m.Condition{
Field: "kind",
Value: "basicAuth",
Mapper: types.Mappers{
m.UntypedMove{
From: "data/username",
To: "username",
},
m.UntypedMove{
From: "data/password",
To: "password",
},
m.Base64{
Field: "username",
IgnoreDefinition: true,
},
m.Base64{
Field: "password",
IgnoreDefinition: true,
},
m.SetValue{
Field: "type",
Value: "basicAuth",
IgnoreDefinition: true,
},
},
},
m.Condition{
Field: "kind",
Value: "certificate",
Mapper: types.Mappers{
m.UntypedMove{
From: "data/tls.crt",
To: "certs",
},
m.UntypedMove{
From: "data/tls.key",
To: "key",
},
m.Base64{
Field: "certs",
IgnoreDefinition: true,
},
m.Base64{
Field: "key",
IgnoreDefinition: true,
},
m.AnnotationField{Field: "certFingerprint", IgnoreDefinition: true},
m.AnnotationField{Field: "cn", IgnoreDefinition: true},
m.AnnotationField{Field: "version", IgnoreDefinition: true},
m.AnnotationField{Field: "issuer", IgnoreDefinition: true},
m.AnnotationField{Field: "issuedAt", IgnoreDefinition: true},
m.AnnotationField{Field: "algorithm", IgnoreDefinition: true},
m.AnnotationField{Field: "serialNumber", IgnoreDefinition: true},
m.AnnotationField{Field: "keySize", IgnoreDefinition: true},
m.AnnotationField{Field: "subjectAlternativeNames", IgnoreDefinition: true},
m.SetValue{
Field: "type",
Value: "certificate",
IgnoreDefinition: true,
},
},
},
m.Condition{
Field: "kind",
Value: "dockerCredential",
Mapper: types.Mappers{
m.Base64{
Field: "data/.dockercfg",
IgnoreDefinition: true,
},
m.JSONEncode{
Field: "data/.dockercfg",
IgnoreDefinition: true,
},
m.UntypedMove{
From: "data/.dockercfg",
To: "registries",
},
m.Base64{
Field: "data/.dockerconfigjson",
IgnoreDefinition: true,
},
m.JSONEncode{
Field: "data/.dockerconfigjson",
IgnoreDefinition: true,
},
m.UntypedMove{
From: "data/.dockerconfigjson/auths",
To: "registries",
},
m.SetValue{
Field: "type",
Value: "dockerCredential",
IgnoreDefinition: true,
},
},
},
m.Condition{
Field: "kind",
Value: "serviceAccountToken",
Mapper: types.Mappers{
m.UntypedMove{
From: "annotations!kubernetes.io/service-account.name",
To: "accountName",
Separator: "!",
},
m.UntypedMove{
From: "annotations!kubernetes.io/service-account.uid",
To: "accountUid",
Separator: "!",
},
m.UntypedMove{
From: "data/ca.crt",
To: "caCrt",
},
m.UntypedMove{
From: "data/namespace",
To: "namespace",
},
m.UntypedMove{
From: "data/token",
To: "token",
},
m.Base64{
Field: "caCrt",
IgnoreDefinition: true,
},
m.Base64{
Field: "namespace",
IgnoreDefinition: true,
},
m.Base64{
Field: "token",
IgnoreDefinition: true,
},
m.SetValue{
Field: "type",
Value: "serviceAccountToken",
IgnoreDefinition: true,
},
},
},
).
AddMapperForType(&Version, v3.RegistryCredential{}, RegistryCredentialMapper{}).
MustImportAndCustomize(&Version, v1.Secret{}, func(schema *types.Schema) {
schema.MustCustomizeField("kind", func(f types.Field) types.Field {
f.Options = []string{
"Opaque",
"serviceAccountToken",
"dockerCredential",
"basicAuth",
"sshAuth",
"certificate",
}
return f
})
}, projectOverride{}).
MustImportAndCustomize(&Version, v3.ServiceAccountToken{}, func(schema *types.Schema) {
schema.BaseType = "secret"
schema.Mapper = schemas.Schema(&Version, "secret").Mapper
}, projectOverride{}).
MustImportAndCustomize(&Version, v3.DockerCredential{}, func(schema *types.Schema) {
schema.BaseType = "secret"
schema.Mapper = schemas.Schema(&Version, "secret").Mapper
}, projectOverride{}).
MustImportAndCustomize(&Version, v3.Certificate{}, func(schema *types.Schema) {
schema.BaseType = "secret"
schema.Mapper = schemas.Schema(&Version, "secret").Mapper
}, projectOverride{}).
MustImportAndCustomize(&Version, v3.BasicAuth{}, func(schema *types.Schema) {
schema.BaseType = "secret"
schema.Mapper = schemas.Schema(&Version, "secret").Mapper
}, projectOverride{}).
MustImportAndCustomize(&Version, v3.SSHAuth{}, func(schema *types.Schema) {
schema.BaseType = "secret"
schema.Mapper = schemas.Schema(&Version, "secret").Mapper
}, projectOverride{})
}

View File

@ -0,0 +1,54 @@
package schema
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
type ServiceKindMapper struct {
}
func (s ServiceKindMapper) FromInternal(data map[string]interface{}) {
if data == nil {
return
}
targetWorkloadIds := data["targetWorkloadIds"]
targetServiceIds := data["targetServiceIds"]
clusterIP := data["clusterIp"]
hostname := data["hostname"]
if !convert.IsEmpty(targetWorkloadIds) || !convert.IsEmpty(targetServiceIds) {
data["serviceKind"] = "Alias"
} else if !convert.IsEmpty(hostname) {
data["serviceKind"] = "CName"
} else if clusterIP == "None" {
data["serviceKind"] = "ARecord"
}
}
func (s ServiceKindMapper) ToInternal(data map[string]interface{}) {
if data == nil {
return
}
str := convert.ToString(data["serviceKind"])
switch str {
case "Alias":
fallthrough
case "ARecord":
fallthrough
case "CName":
data["serviceKind"] = "ClusterIP"
data["clusterIp"] = "None"
}
if !convert.IsEmpty(data["hostname"]) {
data["kind"] = "ExternalName"
data["clusterIp"] = "None"
}
}
func (s ServiceKindMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
return nil
}

View File

@ -60,3 +60,59 @@ type Link struct {
Name string `json:"name"`
Alias string `json:"alias"`
}
type ServiceAccountToken struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
AccountName string `json:"accountName"`
AccountUID string `json:"accountUid"`
Token string `json:"token" norman:"writeOnly"`
CACRT string `json:"caCrt"`
NamespaceID string `json:"namespaceId" norman:"type=reference[namespace]"`
}
type DockerCredential struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Registries map[string]RegistryCredential `json:"registries"`
}
type RegistryCredential struct {
Username string `json:"username"`
Password string `json:"password" norman:"writeOnly"`
Auth string `json:"auth"`
}
type Certificate struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Certs string `json:"certs"`
Key string `json:"key" norman:"writeOnly"`
CertFingerprint string `json:"certFingerprint"`
CN string `json:"cn"`
Version string `json:"version"`
Issuer string `json:"issuer"`
IssuedAt string `json:"issuedAt"`
Algorithm string `json:"Algorithm"`
SerialNumber string `json:"serialNumber"`
KeySize string `json:"keySize"`
SubjectAlternativeNames string `json:"subjectAlternativeNames"`
}
type BasicAuth struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Username string `json:"username"`
Password string `json:"password" norman:"writeOnly"`
}
type SSHAuth struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
PrivateKey string `json:"privateKey"`
}

View File

@ -13,7 +13,9 @@ import (
managementv3 "github.com/rancher/types/apis/management.cattle.io/v3"
managementSchema "github.com/rancher/types/apis/management.cattle.io/v3/schema"
projectv3 "github.com/rancher/types/apis/project.cattle.io/v3"
projectSchema "github.com/rancher/types/apis/project.cattle.io/v3/schema"
rbacv1 "github.com/rancher/types/apis/rbac.authorization.k8s.io/v1"
projectClient "github.com/rancher/types/client/project/v3"
"github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -24,6 +26,17 @@ import (
"k8s.io/client-go/tools/record"
)
var (
ProjectTypes = []string{
projectClient.BasicAuthType,
projectClient.CertificateType,
projectClient.DockerCredentialType,
projectClient.ServiceAccountTokenType,
projectClient.SecretType,
projectClient.SSHAuthType,
}
)
type ManagementContext struct {
eventBroadcaster record.EventBroadcaster
@ -145,6 +158,11 @@ func NewManagementContext(config rest.Config) (*ManagementContext, error) {
context.Schemas = types.NewSchemas().
AddSchemas(managementSchema.Schemas)
for _, projectType := range ProjectTypes {
schema := projectSchema.Schemas.Schema(&projectSchema.Version, projectType)
context.Schemas.AddSchema(*schema)
}
context.Scheme = runtime.NewScheme()
managementv3.AddToScheme(context.Scheme)