client.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package bluegreen
  2. import (
  3. "context"
  4. "fmt"
  5. "strings"
  6. _ "github.com/golang/mock/mockgen/model"
  7. v1 "github.com/kakao/bluegreen/api/v1"
  8. appsv1 "k8s.io/api/apps/v1"
  9. corev1 "k8s.io/api/core/v1"
  10. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  11. ctrl "sigs.k8s.io/controller-runtime"
  12. "sigs.k8s.io/controller-runtime/pkg/client"
  13. )
  14. //go:generate go run github.com/golang/mock/mockgen@v1.6.0 -package bluegreen -destination mock.gen.go . Client
  15. type Client interface {
  16. client.Reader
  17. CreateOrUpdateService(ctx context.Context, owner *v1.BlueGreen) error
  18. CreateOrUpdateDeployment(ctx context.Context, owner *v1.BlueGreen, phase v1.BlueOrGreen, podSpec corev1.PodSpec) error
  19. UpdateStatus(ctx context.Context, bg *v1.BlueGreen) error
  20. }
  21. var _ Client = &BlueGreenClient{}
  22. type BlueGreenClient struct {
  23. client.Client
  24. }
  25. func (r *BlueGreenClient) UpdateStatus(ctx context.Context, bg *v1.BlueGreen) error {
  26. return r.Status().Update(ctx, bg)
  27. }
  28. func (r *BlueGreenClient) CreateOrUpdateDeployment(ctx context.Context, owner *v1.BlueGreen, phase v1.BlueOrGreen, podSpec corev1.PodSpec) error {
  29. deploy := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: owner.Namespace, Name: deploymentName(owner.Name, phase)}}
  30. if _, err := ctrl.CreateOrUpdate(ctx, r.Client, deploy, func() error {
  31. if err := ctrl.SetControllerReference(owner, deploy, r.Scheme()); err != nil {
  32. return err
  33. }
  34. label := map[string]string{
  35. "app.kubernetes.io/managed-by": "app.demo.kakao.com",
  36. "app.kubernetes.io/name": owner.Name,
  37. "app.kubernetes.io/phase": string(phase),
  38. }
  39. deploy.Spec.Selector = &metav1.LabelSelector{MatchLabels: label}
  40. deploy.Spec.Template = corev1.PodTemplateSpec{
  41. ObjectMeta: metav1.ObjectMeta{Labels: label},
  42. Spec: podSpec,
  43. }
  44. return nil
  45. }); err != nil {
  46. return err
  47. }
  48. return nil
  49. }
  50. func (r *BlueGreenClient) CreateOrUpdateService(ctx context.Context, owner *v1.BlueGreen) error {
  51. svc := &corev1.Service{ObjectMeta: metav1.ObjectMeta{Namespace: owner.Namespace, Name: owner.Name}}
  52. if _, err := ctrl.CreateOrUpdate(ctx, r.Client, svc,
  53. func() error {
  54. if err := ctrl.SetControllerReference(owner, svc, r.Scheme()); err != nil {
  55. return err
  56. }
  57. svc.Spec.Ports = []corev1.ServicePort{
  58. {Name: "http", Protocol: corev1.ProtocolTCP, Port: 80},
  59. }
  60. svc.Spec.Selector = map[string]string{
  61. "app.kubernetes.io/managed-by": "app.demo.kakao.com",
  62. "app.kubernetes.io/name": owner.Name,
  63. "app.kubernetes.io/phase": string(owner.Spec.RouteTo),
  64. }
  65. return nil
  66. },
  67. ); err != nil {
  68. return err
  69. }
  70. return nil
  71. }
  72. func deploymentName(name string, phase v1.BlueOrGreen) string {
  73. return fmt.Sprintf("%s-%s", name, strings.ToLower(string(phase)))
  74. }