diff --git a/apis/cluster.cattle.io/v1/schema/schema.go b/apis/cluster.cattle.io/v1/schema/schema.go index a0c23e7b..02c217ce 100644 --- a/apis/cluster.cattle.io/v1/schema/schema.go +++ b/apis/cluster.cattle.io/v1/schema/schema.go @@ -13,13 +13,13 @@ var ( Group: "cluster.cattle.io", Path: "/v1-cluster", SubContexts: map[string]bool{ - "projects": true, + "clusters": true, }, } Schemas = commonmappers.Add(&Version, types.NewSchemas()). - AddMapperForType(&Version, v1.Cluster{}, m.NewObject(nil)). - AddMapperForType(&Version, v1.ClusterNode{}, m.NewObject(nil)). + AddMapperForType(&Version, v1.Cluster{}, m.NewObject()). + AddMapperForType(&Version, v1.ClusterNode{}, m.NewObject()). MustImport(&Version, v1.Cluster{}). MustImport(&Version, v1.ClusterNode{}) ) diff --git a/apis/workload.cattle.io/v1/schema/mapper/node_address.go b/apis/workload.cattle.io/v1/schema/mapper/node_address.go new file mode 100644 index 00000000..51d05afe --- /dev/null +++ b/apis/workload.cattle.io/v1/schema/mapper/node_address.go @@ -0,0 +1,29 @@ +package mapper + +import ( + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/mapping/mapper" +) + +type NodeAddressMapper struct { +} + +func (n NodeAddressMapper) FromInternal(data map[string]interface{}) { + addresses, _ := mapper.GetSlice(data, "addresses") + for _, address := range addresses { + t := address["type"] + a := address["address"] + if t == "InternalIP" { + data["IpAddress"] = a + } else if t == "Hostname" { + data["hostname"] = a + } + } +} + +func (n NodeAddressMapper) ToInternal(data map[string]interface{}) { +} + +func (n NodeAddressMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/apis/workload.cattle.io/v1/schema/mapper/os_info.go b/apis/workload.cattle.io/v1/schema/mapper/os_info.go new file mode 100644 index 00000000..a42bbdd5 --- /dev/null +++ b/apis/workload.cattle.io/v1/schema/mapper/os_info.go @@ -0,0 +1,49 @@ +package mapper + +import ( + "strings" + + "github.com/rancher/norman/types" + "github.com/rancher/norman/types/convert" + "github.com/rancher/norman/types/mapping/mapper" +) + +type OSInfo struct { +} + +func (o OSInfo) FromInternal(data map[string]interface{}) { + cpuInfo := map[string]interface{}{ + "count": mapper.GetValueN(data, "capacity", "cpu"), + } + + kib := strings.TrimSuffix(convert.ToString(mapper.GetValueN(data, "capacity", "memory")), "Ki") + memoryInfo := map[string]interface{}{} + + kibNum, err := convert.ToNumber(kib) + if err == nil { + memoryInfo["memTotalKiB"] = kibNum + } + + osInfo := map[string]interface{}{ + "dockerVersion": strings.TrimPrefix(convert.ToString(mapper.GetValueN(data, "nodeInfo", "containerRuntimeVersion")), "docker://"), + "kernelVersion": mapper.GetValueN(data, "nodeInfo", "kernelVersion"), + "operatingSystem": mapper.GetValueN(data, "nodeInfo", "osImage"), + } + + data["info"] = map[string]interface{}{ + "cpu": cpuInfo, + "memory": memoryInfo, + "os": osInfo, + "kubernetes": map[string]interface{}{ + "kubeletVersion": mapper.GetValueN(data, "nodeInfo", "kubeletVersion"), + "kubeProxyVersion": mapper.GetValueN(data, "nodeInfo", "kubeletVersion"), + }, + } +} + +func (o OSInfo) ToInternal(data map[string]interface{}) { +} + +func (o OSInfo) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/apis/workload.cattle.io/v1/schema/mapper/resource.go b/apis/workload.cattle.io/v1/schema/mapper/resource.go index ca386269..00d62f93 100644 --- a/apis/workload.cattle.io/v1/schema/mapper/resource.go +++ b/apis/workload.cattle.io/v1/schema/mapper/resource.go @@ -7,37 +7,46 @@ import ( m "github.com/rancher/norman/types/mapping/mapper" ) -type ResourceRequirementsMapper struct { +type PivotMapper struct { + Plural bool } -func (r ResourceRequirementsMapper) FromInternal(data map[string]interface{}) { +func (r PivotMapper) FromInternal(data map[string]interface{}) { for key, value := range data { mapValue, ok := value.(map[string]interface{}) if !ok { continue } for subKey, subValue := range mapValue { - m.PutValue(data, subValue, subKey, strings.TrimSuffix(key, "s")) + if r.Plural { + m.PutValue(data, subValue, subKey, strings.TrimSuffix(key, "s")) + } else { + m.PutValue(data, subValue, subKey, key) + + } } delete(data, key) } } -func (r ResourceRequirementsMapper) ToInternal(data map[string]interface{}) { +func (r PivotMapper) ToInternal(data map[string]interface{}) { for key, value := range data { mapValue, ok := value.(map[string]interface{}) if !ok { continue } for subKey, subValue := range mapValue { - m.PutValue(data, subValue, subKey, key+"s") - + if r.Plural { + m.PutValue(data, subValue, subKey, key+"s") + } else { + m.PutValue(data, subValue, subKey, key) + } } delete(data, key) } } -func (r ResourceRequirementsMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { +func (r PivotMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { return nil } diff --git a/apis/workload.cattle.io/v1/schema/mapper/statefulset_spec.go b/apis/workload.cattle.io/v1/schema/mapper/statefulset_spec.go new file mode 100644 index 00000000..9d7f92b1 --- /dev/null +++ b/apis/workload.cattle.io/v1/schema/mapper/statefulset_spec.go @@ -0,0 +1,18 @@ +package mapper + +import ( + "github.com/rancher/norman/types" +) + +type StatefulSetSpecMapper struct { +} + +func (s StatefulSetSpecMapper) FromInternal(data map[string]interface{}) { +} + +func (s StatefulSetSpecMapper) ToInternal(data map[string]interface{}) { +} + +func (s StatefulSetSpecMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + return nil +} diff --git a/apis/workload.cattle.io/v1/schema/schema.go b/apis/workload.cattle.io/v1/schema/schema.go index b25b5f50..1185d3a2 100644 --- a/apis/workload.cattle.io/v1/schema/schema.go +++ b/apis/workload.cattle.io/v1/schema/schema.go @@ -6,19 +6,172 @@ import ( "github.com/rancher/types/apis/workload.cattle.io/v1/schema/mapper" "github.com/rancher/types/commonmappers" "k8s.io/api/core/v1" + "k8s.io/kubernetes/staging/src/k8s.io/api/apps/v1beta2" ) var ( Version = types.APIVersion{ Version: "v1", Group: "workload.cattle.io", - Path: "/v1-app", + Path: "/v1-workload", SubContexts: map[string]bool{ - "projects": true, + "projects": true, + "namespaces": true, }, } Schemas = commonmappers.Add(&Version, types.NewSchemas()). + Init(podTypes). + Init(namespaceTypes). + Init(nodeTypes). + Init(replicaSetTypes). + Init(deploymentTypes). + Init(statefulSetTypes) +) + +func statefulSetTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1beta2.StatefulSetUpdateStrategy{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + m.Enum{Field: "type", + Values: map[string][]string{ + "RollingUpdate": {"rollingUpdate"}, + "OnDelete": {"onDelete"}, + }, + }, + m.Move{From: "type", To: "kind"}, + m.Move{From: "rollingUpdate", To: "rollingUpdateConfig"}, + }, + }). + AddMapperForType(&Version, v1beta2.StatefulSetSpec{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &m.Move{ + From: "replicas", + To: "deploy/scale", + }, + m.Enum{Field: "podManagementPolicy", + Values: map[string][]string{ + "OrderedReady": {"ordered"}, + "Parallel": {"parallel"}, + }, + }, + &m.Move{ + From: "podManagementPolicy", + To: "deploy/strategy", + }, + &m.Move{ + From: "revisionHistoryLimit", + To: "deploy/maxRevisions", + }, + m.Drop{"selector"}, + m.SliceToMap{ + Field: "volumeClaimTemplates", + Key: "name", + }, + }, + }). + AddMapperForType(&Version, v1beta2.StatefulSet{}, m.NewObject()). + MustImport(&Version, v1beta2.StatefulSetSpec{}, deployOverride{}). + MustImport(&Version, v1beta2.StatefulSet{}) +} + +func deploymentTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1beta2.DeploymentStrategy{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + m.Enum{Field: "type", + Values: map[string][]string{ + "RollingUpdate": {"rollingUpdate"}, + "Recreate": {"recreate"}, + }, + }, + m.Move{From: "type", To: "kind"}, + m.Move{From: "rollingUpdate", To: "rollingUpdateConfig"}, + }, + }). + AddMapperForType(&Version, v1beta2.DeploymentSpec{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &m.Move{ + From: "replicas", + To: "deploy/scale", + }, + &m.Move{ + From: "minReadySeconds", + To: "deploy/minReadySeconds", + }, + &m.Move{ + From: "progressDeadlineSeconds", + To: "deploy/progressDeadlineSeconds", + }, + &m.Move{ + From: "revisionHistoryLimit", + To: "deploy/maxRevisions", + }, + m.Drop{"selector"}, + m.Move{From: "strategy", To: "updateStrategy"}, + }, + }). + AddMapperForType(&Version, v1beta2.Deployment{}, m.NewObject()). + MustImport(&Version, v1beta2.DeploymentSpec{}, deployOverride{}). + MustImport(&Version, v1beta2.Deployment{}) +} + +func replicaSetTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1beta2.ReplicaSetSpec{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &m.Move{ + From: "replicas", + To: "deploy/scale", + }, + &m.Move{ + From: "minReadySeconds", + To: "deploy/minReadySeconds", + }, + m.Drop{"selector"}, + }, + }). + AddMapperForType(&Version, v1beta2.ReplicaSet{}, m.NewObject()). + MustImport(&Version, v1beta2.ReplicaSetSpec{}, deployOverride{}). + MustImport(&Version, v1beta2.ReplicaSet{}) +} + +func nodeTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.NodeStatus{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &mapper.NodeAddressMapper{}, + &mapper.OSInfo{}, + &m.Drop{"addresses"}, + &m.Drop{"conditions"}, + &m.Drop{"daemonEndpoints"}, + &m.Drop{"images"}, + &m.Drop{"nodeInfo"}, + &m.SliceToMap{Field: "volumesAttached", Key: "devicePath"}, + }, + }). + AddMapperForType(&Version, v1.Node{}, m.NewObject()). + MustImport(&Version, v1.NodeStatus{}, nodeStatusOverride{}). + MustImport(&Version, v1.Node{}) +} +func namespaceTypes(schemas *types.Schemas) *types.Schemas { + return schemas. + AddMapperForType(&Version, v1.NamespaceStatus{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &m.Drop{"phase"}, + }, + }). + AddMapperForType(&Version, v1.NamespaceSpec{}, &types.TypeMapper{ + Mappers: []types.Mapper{ + &m.Drop{"finalizers"}, + }, + }). + AddMapperForType(&Version, v1.Namespace{}, m.NewObject()). + MustImport(&Version, v1.Namespace{}) +} + +func podTypes(schemas *types.Schemas) *types.Schemas { + return schemas. AddMapperForType(&Version, v1.Capabilities{}, &types.TypeMapper{ Mappers: []types.Mapper{ m.Move{From: "add", To: "capAdd"}, @@ -79,6 +232,10 @@ var ( mapper.InitContainerMapper{}, mapper.SchedulingMapper{}, &m.Embed{Field: "securityContext"}, + &m.SliceToMap{ + Field: "volumes", + Key: "name", + }, &m.SliceToMap{ Field: "containers", Key: "name", @@ -98,9 +255,10 @@ var ( }). AddMapperForType(&Version, v1.ResourceRequirements{}, &types.TypeMapper{ Mappers: []types.Mapper{ - mapper.ResourceRequirementsMapper{}, + mapper.PivotMapper{Plural: true}, }, }). + // Must import handlers before Container MustImport(&Version, v1.Handler{}, handlerOverride{}). MustImport(&Version, v1.Probe{}, handlerOverride{}). MustImport(&Version, v1.Container{}, struct { @@ -116,4 +274,4 @@ var ( IPC string }{}). MustImport(&Version, v1.Pod{}) -) +} diff --git a/apis/workload.cattle.io/v1/schema/types.go b/apis/workload.cattle.io/v1/schema/types.go index 74fb1ff1..b41503bd 100644 --- a/apis/workload.cattle.io/v1/schema/types.go +++ b/apis/workload.cattle.io/v1/schema/types.go @@ -3,6 +3,7 @@ package schema import ( "github.com/rancher/norman/types" m "github.com/rancher/norman/types/mapping/mapper" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( @@ -28,6 +29,13 @@ var ( } ) +type ScalingGroup struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec interface{} `json:"spec"` + Status interface{} `json:"status"` +} + type handlerOverride struct { TCP bool } @@ -77,3 +85,42 @@ type deployParams struct { Ordered bool QuorumSize int64 } + +type nodeStatusOverride struct { + IPAddress string + Hostname string + Info NodeInfo +} + +type NodeInfo struct { + CPU CPUInfo + Memory MemoryInfo + OS OSInfo + Kubernetes KubernetesInfo +} + +type CPUInfo struct { + Count int64 +} + +type MemoryInfo struct { + MemTotalKiB int64 +} + +type OSInfo struct { + DockerVersion string + KernelVersion string + OperatingSystem string +} + +type KubernetesInfo struct { + KubeletVersion string + KubeProxyVersion string +} + +type DeployParams struct { +} + +type deployOverride struct { + Deploy *DeployParams +}