api.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package gce
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/coreos/flannel/Godeps/_workspace/src/code.google.com/p/goauth2/compute/serviceaccount"
  6. "github.com/coreos/flannel/Godeps/_workspace/src/code.google.com/p/google-api-go-client/compute/v1"
  7. log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog"
  8. )
  9. type gceAPI struct {
  10. project string
  11. computeService *compute.Service
  12. gceNetwork *compute.Network
  13. gceInstance *compute.Instance
  14. }
  15. func newAPI() (*gceAPI, error) {
  16. client, err := serviceaccount.NewClient(&serviceaccount.Options{})
  17. if err != nil {
  18. return nil, fmt.Errorf("error creating client: %v", err)
  19. }
  20. cs, err := compute.New(client)
  21. if err != nil {
  22. return nil, fmt.Errorf("error creating compute service: %v", err)
  23. }
  24. networkName, err := networkFromMetadata()
  25. if err != nil {
  26. return nil, fmt.Errorf("error getting network metadata: %v", err)
  27. }
  28. prj, err := projectFromMetadata()
  29. if err != nil {
  30. return nil, fmt.Errorf("error getting project: %v", err)
  31. }
  32. instanceName, err := instanceNameFromMetadata()
  33. if err != nil {
  34. return nil, fmt.Errorf("error getting instance name: %v", err)
  35. }
  36. instanceZone, err := instanceZoneFromMetadata()
  37. if err != nil {
  38. return nil, fmt.Errorf("error getting instance zone: %v", err)
  39. }
  40. gn, err := cs.Networks.Get(prj, networkName).Do()
  41. if err != nil {
  42. return nil, fmt.Errorf("error getting network from compute service: %v", err)
  43. }
  44. gi, err := cs.Instances.Get(prj, instanceZone, instanceName).Do()
  45. if err != nil {
  46. return nil, fmt.Errorf("error getting instance from compute service: %v", err)
  47. }
  48. return &gceAPI{
  49. project: prj,
  50. computeService: cs,
  51. gceNetwork: gn,
  52. gceInstance: gi,
  53. }, nil
  54. }
  55. func (api *gceAPI) getRoute(subnet string) (*compute.Route, error) {
  56. routeName := formatRouteName(subnet)
  57. return api.computeService.Routes.Get(api.project, routeName).Do()
  58. }
  59. func (api *gceAPI) deleteRoute(subnet string) (*compute.Operation, error) {
  60. routeName := formatRouteName(subnet)
  61. return api.computeService.Routes.Delete(api.project, routeName).Do()
  62. }
  63. func (api *gceAPI) insertRoute(subnet string) (*compute.Operation, error) {
  64. log.Infof("Inserting route for subnet: %v", subnet)
  65. route := &compute.Route{
  66. Name: formatRouteName(subnet),
  67. DestRange: subnet,
  68. Network: api.gceNetwork.SelfLink,
  69. NextHopInstance: api.gceInstance.SelfLink,
  70. Priority: 1000,
  71. Tags: []string{},
  72. }
  73. return api.computeService.Routes.Insert(api.project, route).Do()
  74. }
  75. func (api *gceAPI) pollOperationStatus(operationName string) error {
  76. for i := 0; i < 100; i++ {
  77. operation, err := api.computeService.GlobalOperations.Get(api.project, operationName).Do()
  78. if err != nil {
  79. return fmt.Errorf("error fetching operation status: %v", err)
  80. }
  81. if operation.Error != nil {
  82. return fmt.Errorf("error running operation: %v", operation.Error)
  83. }
  84. if i%5 == 0 {
  85. log.Infof("%v operation status: %v waiting for completion...", operation.OperationType, operation.Status)
  86. }
  87. if operation.Status == "DONE" {
  88. return nil
  89. }
  90. time.Sleep(time.Second)
  91. }
  92. return fmt.Errorf("timeout waiting for operation to finish")
  93. }
  94. func formatRouteName(subnet string) string {
  95. return fmt.Sprintf("flannel-%s", replacer.Replace(subnet))
  96. }