~dave-cheney/goose/goose

« back to all changes in this revision

Viewing changes to testservices/novaservice/service_http.go

  • Committer: Tarmac
  • Author(s): Andrew Wilkins
  • Date: 2014-06-10 12:27:28 UTC
  • mfrom: (124.1.3 goose)
  • Revision ID: tarmac-20140610122728-ontdj4574u0nfbq2
[r=gz] Add support for Availability Zones

- Added ListAvailabilityZones to Nova client
- Added AvailabilityZone field to RunServerOpts
- Added AvailabilityZone field to ServerDetail
- Updated nova test-service to support all of the above

Availability zones are an OpenStack extension,
so I've made it so that ListAvailabilityZones will
ignore any 404 to the os-availability-zone URL.

https://codereview.appspot.com/103900045/

R=gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
536
536
func (n *Nova) handleRunServer(body []byte, w http.ResponseWriter, r *http.Request) error {
537
537
        var req struct {
538
538
                Server struct {
539
 
                        FlavorRef      string
540
 
                        ImageRef       string
541
 
                        Name           string
542
 
                        Metadata       map[string]string
543
 
                        SecurityGroups []map[string]string `json:"security_groups"`
544
 
                        Networks       []map[string]string
 
539
                        FlavorRef        string
 
540
                        ImageRef         string
 
541
                        Name             string
 
542
                        Metadata         map[string]string
 
543
                        SecurityGroups   []map[string]string `json:"security_groups"`
 
544
                        Networks         []map[string]string
 
545
                        AvailabilityZone string `json:"availability_zone"`
545
546
                }
546
547
        }
547
548
        if err := json.Unmarshal(body, &req); err != nil {
556
557
        if req.Server.FlavorRef == "" {
557
558
                return errBadRequestSrvFlavor
558
559
        }
 
560
        if az := req.Server.AvailabilityZone; az != "" {
 
561
                if !n.availabilityZones[az].State.Available {
 
562
                        return testservices.AvailabilityZoneIsNotAvailable
 
563
                }
 
564
        }
559
565
        n.nextServerId++
560
566
        id := strconv.Itoa(n.nextServerId)
561
567
        uuid, err := newUUID()
590
596
        timestr := time.Now().Format(time.RFC3339)
591
597
        userInfo, _ := userInfo(n.IdentityService, r)
592
598
        server := nova.ServerDetail{
593
 
                Id:        id,
594
 
                UUID:      uuid,
595
 
                Name:      req.Server.Name,
596
 
                TenantId:  n.TenantId,
597
 
                UserId:    userInfo.Id,
598
 
                HostId:    "1",
599
 
                Image:     image,
600
 
                Flavor:    flavorEnt,
601
 
                Status:    nova.StatusActive,
602
 
                Created:   timestr,
603
 
                Updated:   timestr,
604
 
                Addresses: make(map[string][]nova.IPAddress),
 
599
                Id:               id,
 
600
                UUID:             uuid,
 
601
                Name:             req.Server.Name,
 
602
                TenantId:         n.TenantId,
 
603
                UserId:           userInfo.Id,
 
604
                HostId:           "1",
 
605
                Image:            image,
 
606
                Flavor:           flavorEnt,
 
607
                Status:           nova.StatusActive,
 
608
                Created:          timestr,
 
609
                Updated:          timestr,
 
610
                Addresses:        make(map[string][]nova.IPAddress),
 
611
                AvailabilityZone: req.Server.AvailabilityZone,
605
612
        }
606
613
        nextServer := len(n.allServers(nil)) + 1
607
614
        n.buildServerLinks(&server)
1019
1026
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
1020
1027
}
1021
1028
 
 
1029
// handleAvailabilityZones handles the os-availability-zone HTTP API.
 
1030
func (n *Nova) handleAvailabilityZones(w http.ResponseWriter, r *http.Request) error {
 
1031
        switch r.Method {
 
1032
        case "GET":
 
1033
                if ipId := path.Base(r.URL.Path); ipId != "os-availability-zone" {
 
1034
                        return errNotFoundJSON
 
1035
                }
 
1036
                zones := n.allAvailabilityZones()
 
1037
                if len(zones) == 0 {
 
1038
                        // If there are no availability zones defined, act as
 
1039
                        // if we don't support the availability zones extension.
 
1040
                        return errNotFoundJSON
 
1041
                }
 
1042
                resp := struct {
 
1043
                        Zones []nova.AvailabilityZone `json:"availabilityZoneInfo"`
 
1044
                }{zones}
 
1045
                return sendJSON(http.StatusOK, resp, w, r)
 
1046
        }
 
1047
        return fmt.Errorf("unknown request method %q for %s", r.Method, r.URL.Path)
 
1048
}
 
1049
 
1022
1050
// setupHTTP attaches all the needed handlers to provide the HTTP API.
1023
1051
func (n *Nova) SetupHTTP(mux *http.ServeMux) {
1024
1052
        handlers := map[string]http.Handler{
1033
1061
                "/$v/$t/os-security-group-rules": n.handler((*Nova).handleSecurityGroupRules),
1034
1062
                "/$v/$t/os-floating-ips":         n.handler((*Nova).handleFloatingIPs),
1035
1063
                "/$v/$t/os-networks":             n.handler((*Nova).handleNetworks),
 
1064
                "/$v/$t/os-availability-zone":    n.handler((*Nova).handleAvailabilityZones),
1036
1065
        }
1037
1066
        for path, h := range handlers {
1038
1067
                path = strings.Replace(path, "$v", n.VersionPath, 1)