You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

k8s.go 5.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. package poder
  2. import (
  3. "code.gitlink.org.cn/JCCE/PCM/common/tenanter"
  4. "code.gitlink.org.cn/JCCE/PCM/lan_trans/idl/pbpod"
  5. "code.gitlink.org.cn/JCCE/PCM/lan_trans/idl/pbtenant"
  6. "context"
  7. "fmt"
  8. "github.com/golang/glog"
  9. "github.com/pkg/errors"
  10. corev1 "k8s.io/api/core/v1"
  11. "k8s.io/apimachinery/pkg/api/resource"
  12. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  13. k8s "k8s.io/client-go/kubernetes"
  14. "k8s.io/client-go/rest"
  15. "sync"
  16. )
  17. var k8sClientMutex sync.Mutex
  18. type Config struct {
  19. Host string
  20. Token string
  21. Port int
  22. }
  23. type K8SPoder struct {
  24. cli *k8s.Clientset
  25. region tenanter.Region
  26. tenanter tenanter.Tenanter
  27. }
  28. func (k K8SPoder) GetPodRegion(ctx context.Context, req *pbpod.GetPodRegionReq) (*pbpod.GetPodRegionResp, error) {
  29. //todo
  30. var (
  31. regions []*pbtenant.Region
  32. )
  33. huaweiRegionName, _ := tenanter.GetK8SRegionName(0)
  34. region := &pbtenant.Region{
  35. Id: 0,
  36. Name: huaweiRegionName,
  37. }
  38. regions = append(regions, region)
  39. resp := &pbpod.GetPodRegionResp{
  40. Regions: regions,
  41. }
  42. return resp, nil
  43. }
  44. func newK8SClient(tenant tenanter.Tenanter) (Poder, error) {
  45. var (
  46. client *k8s.Clientset
  47. err error
  48. )
  49. switch t := tenant.(type) {
  50. case *tenanter.AccessKeyTenant:
  51. kubeConf := &rest.Config{
  52. Host: fmt.Sprintf("%s:%d", t.GetUrl(), 6443),
  53. BearerToken: t.GetToken(),
  54. TLSClientConfig: rest.TLSClientConfig{
  55. Insecure: true,
  56. },
  57. }
  58. k8sClientMutex.Lock()
  59. client, err = k8s.NewForConfig(kubeConf)
  60. k8sClientMutex.Unlock()
  61. default:
  62. }
  63. if err != nil {
  64. return nil, errors.Wrap(err, "init k8s client error")
  65. }
  66. return &K8SPoder{
  67. cli: client,
  68. region: nil,
  69. tenanter: tenant,
  70. }, nil
  71. }
  72. func (k *K8SPoder) CreatePod(ctx context.Context, req *pbpod.CreatePodReq) (*pbpod.CreatePodResp, error) {
  73. pod := corev1.Pod{
  74. TypeMeta: metav1.TypeMeta{
  75. APIVersion: "core/V1",
  76. Kind: "Pod",
  77. },
  78. ObjectMeta: metav1.ObjectMeta{
  79. Name: req.PodName,
  80. Namespace: req.Namespace,
  81. Labels: map[string]string{"name": "test_api"},
  82. },
  83. Spec: corev1.PodSpec{
  84. RestartPolicy: corev1.RestartPolicyAlways,
  85. Containers: []corev1.Container{
  86. {
  87. Name: req.ContainerName,
  88. Image: req.ContainerImage,
  89. Resources: corev1.ResourceRequirements{
  90. Limits: map[corev1.ResourceName]resource.Quantity{
  91. corev1.ResourceCPU: resource.MustParse(req.CpuPod),
  92. corev1.ResourceMemory: resource.MustParse(req.MemoryPod),
  93. },
  94. },
  95. },
  96. },
  97. },
  98. Status: corev1.PodStatus{},
  99. }
  100. resp, err := k.cli.CoreV1().Pods(req.Namespace).Create(context.TODO(), &pod, metav1.CreateOptions{})
  101. if err != nil {
  102. return nil, errors.Wrap(err, "K8S CreatePod error")
  103. }
  104. glog.Infof("--------------------K8S Pod Instance created--------------------")
  105. isFinished := false
  106. if len(resp.UID) > 0 {
  107. isFinished = true
  108. }
  109. return &pbpod.CreatePodResp{
  110. Finished: isFinished,
  111. RequestId: "K8S pod Name:" + resp.Name,
  112. PodId: string(resp.UID),
  113. PodName: resp.Name,
  114. }, nil
  115. }
  116. func (k K8SPoder) DeletePod(ctx context.Context, req *pbpod.DeletePodReq) (*pbpod.DeletePodResp, error) {
  117. podName := req.PcmId
  118. fmt.Println("K8S ContainerGroup:", podName, " Deleted")
  119. err := k.cli.CoreV1().Pods(req.Namespace).Delete(context.TODO(), podName, metav1.DeleteOptions{})
  120. glog.Infof("--------------------K8S Pod Instance deleted--------------------")
  121. isFinished := true
  122. if err != nil {
  123. isFinished = false
  124. return nil, errors.Wrap(err, "K8S DeletePod error")
  125. }
  126. return &pbpod.DeletePodResp{
  127. Finished: isFinished,
  128. RequestId: "K8S pod Name:" + req.PodName,
  129. PodId: req.PodName,
  130. PodName: req.PodName,
  131. }, nil
  132. }
  133. func (k K8SPoder) UpdatePod(ctx context.Context, req *pbpod.UpdatePodReq) (*pbpod.UpdatePodResp, error) {
  134. qresp, err := k.cli.CoreV1().Pods(req.GetNamespace()).Get(context.TODO(), req.PcmId, metav1.GetOptions{})
  135. if err != nil {
  136. return nil, errors.Wrap(err, "K8S UpdatePod error")
  137. }
  138. pod := corev1.Pod{
  139. TypeMeta: qresp.TypeMeta,
  140. ObjectMeta: metav1.ObjectMeta{
  141. Name: req.PcmId,
  142. Namespace: req.Namespace,
  143. Labels: map[string]string{"name": req.Labels},
  144. },
  145. Spec: qresp.Spec,
  146. Status: qresp.Status,
  147. }
  148. pod.Spec.Containers[0].Image = req.ContainerImage
  149. resp, err := k.cli.CoreV1().Pods(req.Namespace).Update(context.TODO(), &pod, metav1.UpdateOptions{})
  150. if err != nil {
  151. return nil, errors.Wrap(err, "K8S UpdatePod error")
  152. }
  153. glog.Infof("--------------------K8S Pod Instance updated--------------------")
  154. isFinished := false
  155. if len(resp.UID) > 0 {
  156. isFinished = true
  157. }
  158. return &pbpod.UpdatePodResp{
  159. Finished: isFinished,
  160. RequestId: "K8S pod Name:" + req.PodName,
  161. PodId: string(resp.UID),
  162. PodName: req.PodName,
  163. }, nil
  164. }
  165. func (k K8SPoder) ListPodDetail(ctx context.Context, req *pbpod.ListPodDetailReq) (*pbpod.ListPodDetailResp, error) {
  166. resp, err := k.cli.CoreV1().Pods(req.GetNamespace()).List(context.TODO(), metav1.ListOptions{})
  167. if err != nil {
  168. return nil, errors.Wrap(err, "K8S ListDetail pod error")
  169. }
  170. var pods = make([]*pbpod.PodInstance, len(resp.Items))
  171. for k, v := range resp.Items {
  172. pods[k] = &pbpod.PodInstance{
  173. Provider: pbtenant.CloudProvider_k8s,
  174. AccountName: req.AccountName,
  175. PcmId: v.Name,
  176. PodId: string(v.GetUID()),
  177. PodName: v.Name,
  178. ContainerImage: v.Spec.Containers[0].Image,
  179. ContainerName: v.Spec.Containers[0].Name,
  180. CpuPod: v.Spec.Containers[0].Resources.Requests.Cpu().String(),
  181. MemoryPod: v.Spec.Containers[0].Resources.Requests.Memory().String(),
  182. Namespace: v.Namespace,
  183. Status: string(v.Status.Phase),
  184. }
  185. }
  186. glog.Infof("--------------------Huawei CCI Instance updated--------------------")
  187. isFinished := false
  188. if len(pods) < int(req.PageSize) {
  189. isFinished = true
  190. }
  191. return &pbpod.ListPodDetailResp{
  192. Pods: pods,
  193. Finished: isFinished,
  194. PageNumber: req.PageNumber + 1,
  195. PageSize: req.PageSize,
  196. }, nil
  197. }

PCM is positioned as Software stack over Cloud, aiming to build the standards and ecology of heterogeneous cloud collaboration for JCC in a non intrusive and autonomous peer-to-peer manner.