func (self TaskAPI) ServeHTTP(w http.ResponseWriter, req *http.Request) { switch { case match(req, `GET /v1/tasks`): limit := paramValue(req, "limit", "") if invalidlimit(limit) { bailWithError(w, ClientErrorf("invalid limit supplied")) return } tasks, err := self.Data.GetAllTasks( &db.TaskFilter{ SkipActive: paramEquals(req, "active", "f"), SkipInactive: paramEquals(req, "active", "t"), ForStatus: paramValue(req, "status", ""), Limit: limit, }, ) if err != nil { bail(w, err) return } JSON(w, tasks) return case match(req, `GET /v1/task/[a-fA-F0-9-]+`): re := regexp.MustCompile(`^/v1/task/([a-fA-F0-9-]+)`) id := uuid.Parse(re.FindStringSubmatch(req.URL.Path)[1]) task, err := self.Data.GetTask(id) if err != nil { bail(w, err) return } if task == nil { w.WriteHeader(404) return } JSON(w, task) return case match(req, `DELETE /v1/task/[a-fA-F0-9-]+`): // cancel re := regexp.MustCompile(`^/v1/task/([a-fA-F0-9-]+)`) id := uuid.Parse(re.FindStringSubmatch(req.URL.Path)[1]) err := self.Data.CancelTask(id, time.Now()) if err != nil { bail(w, err) } JSONLiteral(w, fmt.Sprintf(`{"ok":"canceled"}`)) return } w.WriteHeader(501) return }
func TestMinionList(t *testing.T) { tc := mustNewTestClient("fixtures/minion-list") defer tc.recorder.Stop() minionNames := []string{ "Bob", "Kevin", "Stuart", } wantMinions := []uuid.UUID{ uuid.Parse("f827bffd-bd9e-5441-be36-a92a51d0b79e"), // Bob uuid.Parse("46ce0385-0e2b-5ede-8279-9cd98c268170"), // Kevin uuid.Parse("f87cf58e-1e19-57e1-bed3-9dff5064b86a"), // Stuart } // Convert minion uuids as strings for // sorting and equality testing var wantMinionsAsString []string for _, m := range wantMinions { wantMinionsAsString = append(wantMinionsAsString, m.String()) } sort.Strings(wantMinionsAsString) // Register our minions in etcd for _, name := range minionNames { cfg := &minion.EtcdMinionConfig{ Name: name, EtcdConfig: tc.config, } m, err := minion.NewEtcdMinion(cfg) if err != nil { t.Fatal(err) } err = m.SetName(name) if err != nil { t.Error(err) } } // Get minions from etcd gotMinions, err := tc.client.MinionList() if err != nil { t.Fatal(err) } // Convert retrieved minion uuids as string for // sorting and equality testing var gotMinionsAsString []string for _, m := range gotMinions { gotMinionsAsString = append(gotMinionsAsString, m.String()) } sort.Strings(gotMinionsAsString) if !reflect.DeepEqual(wantMinionsAsString, gotMinionsAsString) { t.Errorf("want %q minions, got %q minions", wantMinions, gotMinions) } }
func TestUniqueKeyCreation(t *testing.T) { uniqueKey := NewUniqueKey("") if uuid.Parse(uniqueKey.String()) == nil { t.Error("Invalid uuid generated") } uniqueKey.Next() if uuid.Parse(uniqueKey.String()) == nil { t.Error("Invalid uuid generated") } }
// JobHTTPGet is responsible for retrieving a Job from the database and returning // its record as a JSON object. The UUID for the job is extracted from the basename // of the URL path and must be a valid UUID. func (h *HTTPAPI) JobHTTPGet(writer http.ResponseWriter, request *http.Request) { logger.Printf("Handling GET request for %s", request.URL.Path) baseName := path.Base(request.URL.Path) if baseName == "" { WriteRequestError(writer, "The path must contain a job UUID") return } logger.Printf("Requested job UUID: %s", baseName) if uuid.Parse(baseName) == nil { WriteRequestError(writer, fmt.Sprintf("The base of the path must be a UUID: %s", baseName)) return } jr, err := h.d.GetJob(baseName) if err != nil { WriteRequestError(writer, err.Error()) return } if jr == nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte(fmt.Sprintf("Job %s was not found", baseName))) return } marshalled, err := json.Marshal(jr) if err != nil { writer.WriteHeader(http.StatusInternalServerError) writer.Write([]byte(err.Error())) return } logger.Printf("Response for job lookup by UUID %s:\n%s", baseName, string(marshalled[:])) writer.Write(marshalled) }
// LastEventHTTP handles HTTP requests for looking up a job's last event. The // job is looked up by its invocation ID. JSON is written to the response body // in the following format: // // { // "state" : { // "uuid" : "", // "status" : "", // "completion_date" : "" // } // } // // 'uuid' will be in the normal UUID format of 32 hex digits in 5 groups // delimited by '-'. For example: 'bf6ff4a0-7bcf-11e4-b116-123b93f75cba'. // // 'status' will be a one of 'Submitted', 'Running', 'Completed', or 'Failed'. // // 'completion_date' will be a timestamp that looks like // '2006-01-02T15:04:05Z07:00'. func (h *HTTPAPI) LastEventHTTP(writer http.ResponseWriter, request *http.Request) { logger.Printf("Handling GET request for %s", request.URL.Path) baseName := path.Base(request.URL.Path) if baseName == "" { WriteRequestError(writer, "The path must contain an invocation UUID") return } logger.Printf("Requested job UUID: %s", baseName) if uuid.Parse(baseName) == nil { WriteRequestError(writer, fmt.Sprintf("The base of the path must be a UUID: %s", baseName)) return } jr, err := h.d.GetJobByInvocationID(baseName) if err != nil { WriteRequestError(writer, err.Error()) return } if jr == nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte(fmt.Sprintf("Job %s was not found", baseName))) return } lastCondorJobEvent, err := h.d.GetLastCondorJobEvent(jr.ID) if err != nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte(fmt.Sprintf("Last event for job %s using invocation %s was not found", jr.ID, baseName))) return } lastJobEvent, err := h.d.GetCondorJobEvent(lastCondorJobEvent.CondorJobEventID) if err != nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte(fmt.Sprintf("JobEvent %s was not found for last event lookup", lastCondorJobEvent.CondorJobEventID))) return } condorEvent, err := h.d.GetCondorEvent(lastJobEvent.CondorEventID) if err != nil { writer.WriteHeader(http.StatusNotFound) writer.Write([]byte(fmt.Sprintf("CondorEvent %s was not found for last event lookup", lastJobEvent.CondorEventID))) return } appEvent := &Event{ EventNumber: condorEvent.EventNumber, CondorID: jr.CondorID, AppID: jr.AppID, InvocationID: jr.InvocationID, User: jr.Submitter, EventName: condorEvent.EventName, ExitCode: jr.ExitCode, } jobState := NewJobState(appEvent) marshalled, err := json.Marshal(jobState) if err != nil { writer.WriteHeader(http.StatusInternalServerError) writer.Write([]byte(err.Error())) return } logger.Printf("Response for last event lookup by invocation %s:\n%s", baseName, string(marshalled[:])) writer.Write(marshalled) }
func PodFromPodHome(node types.NodeName, home string) (*Pod, error) { // Check if the pod home is namespaced by a UUID by splitting on a hyphen and // checking the last part. If it parses as a UUID, pass it to newPodWithHome. // Otherwise, pass a nil uniqueKey homeParts := strings.Split(filepath.Base(home), "-") var uniqueKey types.PodUniqueKey podUUID := uuid.Parse(homeParts[len(homeParts)-1]) if podUUID != nil { uniqueKey = types.PodUniqueKey(podUUID.String()) } temp := Pod{ home: home, node: node, } manifest, err := temp.CurrentManifest() if err == NoCurrentManifest { return nil, util.Errorf("No current manifest set, this is not an extant pod directory") } else if err != nil { return nil, err } return newPodWithHome(manifest.ID(), uniqueKey, home, node), nil }
// AssertID checks whether a string is a valid id func AssertID(id string) { if uuid := uuid.Parse(id); uuid == nil { log.WithFields(log.Fields{ "id": id, }).Fatal("invalid id") } }
func FindArchivesFor(target Target, show int) (Archive, uuid.UUID, error) { archives, err := GetArchives(ArchiveFilter{ Target: target.UUID, Status: "valid", }) if err != nil { return Archive{}, nil, err } if len(archives) == 0 { return Archive{}, nil, fmt.Errorf("no valid backup archives found for target %s", target.Name) } if show > len(archives) { show = len(archives) } else { archives = archives[:show] } t := tui.NewTable("UUID", "Taken at", "Expires at", "Status", "Notes") for _, archive := range archives { t.Row(archive, archive.UUID, archive.TakenAt.Format(time.RFC1123Z), archive.ExpiresAt.Format(time.RFC1123Z), archive.Status, archive.Notes) } want := tui.Menu( fmt.Sprintf("Here are the %d most recent backup archives for target %s:", show, target.Name), &t, "Which backup archive would you like to restore?") return want.(Archive), uuid.Parse(want.(Archive).UUID), nil }
func init() { u, err := fb.NewUser(uuid.Parse("9d11d024-a100-4045-a5b7-9f1ccf96cc9f"), "mrsmith") if err != nil { panic(fmt.Sprintf("Error creating user: %s\n", err)) } testUser = u }
func (h *Host) Images() ([]*Image, error) { mm, _ := filepath.Glob(h.Path("images/*/manifest")) rv := make([]*Image, 0, len(mm)) for _, m := range mm { d := filepath.Dir(m) if fi, err := os.Lstat(d); err != nil { return nil, err } else { if !fi.IsDir() { // This is a checksum symlink, skip it. // TODO: are checksum symlinks useful, or harmful by not being DRY? continue } } if id := uuid.Parse(filepath.Base(d)); id == nil { return nil, errors.Errorf("Invalid UUID: %#v", filepath.Base(d)) } else if img, err := LoadImage(h, id); err != nil { id := filepath.Base(d) if img != nil { id = img.UUID.String() } h.ui.Printf("WARNING: images/%v: %v", id, err) } else { rv = append(rv, img) } } return rv, nil }
func (h *Host) getLocalImage(hash types.Hash, name types.ACIdentifier, labels types.Labels) (*Image, error) { if hash.Empty() && name.Empty() { return nil, errors.Trace(ErrUsage) } if !hash.Empty() { if idStr, err := os.Readlink(h.Path("images", hash.String())); os.IsNotExist(err) { return nil, ErrNotFound } else if err != nil { return nil, errors.Trace(err) } else if id := uuid.Parse(idStr); id == nil { return nil, errors.Errorf("Invalid UUID: %v", idStr) } else if img, err := LoadImage(h, id); err != nil { return nil, errors.Trace(err) } else { return img, nil } } else if imgs, err := h.Images(); err != nil { return nil, errors.Trace(err) } else { for _, img := range imgs { if img.Manifest.Name != name { continue } if !acutil.MatchLabels(labels, img.Manifest.Labels) { continue } // TODO: multiple matches? return img, nil } return nil, ErrNotFound } }
func getOrPreparePod(args []string) (*jetpack.Pod, error) { switch len(args) { case 0: return nil, ErrUsage case 1: if id := uuid.Parse(args[0]); id != nil { // Pod UUID return Host.GetPod(id) } fallthrough default: if pm, err := getPodManifest(args); err != nil { return nil, err } else if pod, err := Host.CreatePod(pm); err != nil { return nil, err } else { if SaveID != "" { if err := ioutil.WriteFile(SaveID, []byte(pod.UUID.String()), 0644); err != nil { return nil, err } } return pod, nil } } }
// NewProcessor creates a new processor that will run the build jobs on the // given channel using the given provider and getting build scripts from the // generator. func NewProcessor(ctx gocontext.Context, hostname string, buildJobsChan <-chan Job, provider backend.Provider, generator BuildScriptGenerator, canceller Canceller, hardTimeout, logTimeout, scriptUploadTimeout, startupTimeout time.Duration) (*Processor, error) { uuidString, _ := context.ProcessorFromContext(ctx) processorUUID := uuid.Parse(uuidString) ctx, cancel := gocontext.WithCancel(ctx) return &Processor{ ID: processorUUID, hostname: hostname, hardTimeout: hardTimeout, logTimeout: logTimeout, scriptUploadTimeout: scriptUploadTimeout, startupTimeout: startupTimeout, ctx: ctx, buildJobsChan: buildJobsChan, provider: provider, generator: generator, canceller: canceller, graceful: make(chan struct{}), terminate: cancel, CurrentStatus: "new", }, nil }
// Executes the "queue" command func execQueueCommand(c *cli.Context) error { if len(c.Args()) == 0 { return cli.NewExitError(errNoMinion.Error(), 64) } minion := uuid.Parse(c.Args()[0]) if minion == nil { return cli.NewExitError(errInvalidUUID.Error(), 64) } klient := newEtcdMinionClientFromFlags(c) // Ignore errors about missing queue directory queue, err := klient.MinionTaskQueue(minion) if err != nil { if eerr, ok := err.(client.Error); !ok || eerr.Code != client.ErrorCodeKeyNotFound { return cli.NewExitError(err.Error(), 1) } } if len(queue) == 0 { return nil } table := uitable.New() table.MaxColWidth = 40 table.AddRow("TASK", "STATE", "RECEIVED") for _, t := range queue { table.AddRow(t.ID, t.State, time.Unix(t.TimeReceived, 0)) } fmt.Println(table) return nil }
// Deduces a PodUniqueKey from a consul path. This is useful as pod keys are transitioned // from using node name and pod ID to using UUIDs. // Input is expected to have 3 '/' separated sections, e.g. 'intent/<node>/<pod_id>' or // 'intent/<node>/<pod_uuid>' if the prefix is "intent" or "reality" // // /hooks is also a valid pod prefix and the key under it will not be a uuid. func PodUniqueKeyFromConsulPath(consulPath string) (*types.PodUniqueKey, error) { keyParts := strings.Split(consulPath, "/") if len(keyParts) == 0 { return nil, util.Errorf("Malformed key '%s'", consulPath) } if keyParts[0] == "hooks" { return nil, nil } if len(keyParts) != 3 { return nil, util.Errorf("Malformed key '%s'", consulPath) } // Unforunately we can't use kp.INTENT_TREE and kp.REALITY_TREE here because of an import cycle if keyParts[0] != "intent" && keyParts[0] != "reality" { return nil, util.Errorf("Unrecognized key tree '%s' (must be intent or reality)", keyParts[0]) } // Parse() returns nil if the input string does not match the uuid spec if uuid.Parse(keyParts[2]) != nil { return &types.PodUniqueKey{ ID: keyParts[2], }, nil } return nil, nil }
func (k *Key) UnmarshalJSON(j []byte) (err error) { keyJSON := new(plainKeyJSON) err = json.Unmarshal(j, &keyJSON) if err != nil { return err } u := new(uuid.UUID) *u = uuid.Parse(keyJSON.Id) k.Id = *u addr, err := hex.DecodeString(keyJSON.Address) if err != nil { return err } privkey, err := hex.DecodeString(keyJSON.PrivateKey) if err != nil { return err } k.Address = common.BytesToAddress(addr) k.PrivateKey = ToECDSA(privkey) return nil }
// Executes the "queue" command func execQueueCommand(c *cli.Context) { if len(c.Args()) == 0 { displayError(errMissingMinion, 64) } minion := uuid.Parse(c.Args()[0]) if minion == nil { displayError(errInvalidUUID, 64) } client := newEtcdMinionClientFromFlags(c) // Ignore errors about missing queue directory queue, err := client.MinionTaskQueue(minion) if err != nil { if eerr, ok := err.(etcdclient.Error); !ok || eerr.Code != etcdclient.ErrorCodeKeyNotFound { displayError(err, 1) } } if len(queue) == 0 { return } table := uitable.New() table.MaxColWidth = 40 table.AddRow("TASK", "COMMAND", "STATE", "TIME") for _, task := range queue { table.AddRow(task.TaskID, task.Command, task.State, time.Unix(task.TimeReceived, 0)) } fmt.Println(table) }
func ShowTask(task Task) { t := tui.NewReport() t.Add("UUID", task.UUID) t.Add("Owner", task.Owner) t.Add("Type", task.Op) t.Add("Status", task.Status) t.Break() started := "(pending)" stopped := "(not yet started)" if !task.StartedAt.IsZero() { stopped = "(running)" started = task.StartedAt.Format(time.RFC1123Z) } if !task.StoppedAt.IsZero() { stopped = task.StoppedAt.Format(time.RFC1123Z) } t.Add("Started at", started) t.Add("Stopped at", stopped) t.Break() if job, err := GetJob(uuid.Parse(task.JobUUID)); err == nil { t.Add("Job", fmt.Sprintf("%s (%s)", job.Name, task.JobUUID)) } if task.ArchiveUUID != "" { t.Add("Archive UUID", task.ArchiveUUID) } t.Break() t.Add("Log", task.Log) t.Output(os.Stdout) }
// nodesForVolCreate returns a list of Nodes which volume create touches func nodesForVolCreate(req *volume.VolCreateRequest) ([]uuid.UUID, error) { var nodes []uuid.UUID for _, b := range req.Bricks { // Bricks specified can have one of the following formats: // <peer-uuid>:<brick-path> // <ip>:<port>:<brick-path> // <ip>:<brick-path> // TODO: Peer names, as of today, aren't unique. Support it ? // TODO: Change API to have host and path as separate fields host, _, err := utils.ParseHostAndBrickPath(b) if err != nil { return nil, err } id := uuid.Parse(host) if id == nil { // Host specified is IP or IP:port id, err = peer.GetPeerIDByAddrF(host) if err != nil { return nil, err } } nodes = append(nodes, id) } return nodes, nil }
func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byte, keyId []byte, err error) { keyId = uuid.Parse(keyProtected.Id) mac, err := hex.DecodeString(keyProtected.Crypto.MAC) if err != nil { return nil, nil, err } iv, err := hex.DecodeString(keyProtected.Crypto.CipherParams.IV) if err != nil { return nil, nil, err } cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText) if err != nil { return nil, nil, err } derivedKey, err := getKDFKey(keyProtected.Crypto, auth) if err != nil { return nil, nil, err } calculatedMAC := Sha3(derivedKey[16:32], cipherText) if !bytes.Equal(calculatedMAC, mac) { return nil, nil, errors.New("Decryption failed: MAC mismatch") } plainText, err := aesCBCDecrypt(Sha3(derivedKey[:16])[:16], cipherText, iv) if err != nil { return nil, nil, err } return plainText, keyId, err }
func (ma *mgoAPI) Read(collection string, uuidString string) (found bool, res resource, err error) { newSession := ma.session.Copy() defer newSession.Close() coll := newSession.DB(ma.dbName).C(collection) bsonUUID := bson.Binary{Kind: 0x04, Data: []byte(uuid.Parse(uuidString))} var bsonResource map[string]interface{} if err = coll.Find(bson.M{uuidName: bsonUUID}).One(&bsonResource); err != nil { if err == mgo.ErrNotFound { return false, res, nil } return false, res, err } uuidData := bsonResource["uuid"].(bson.Binary).Data res = resource{ UUID: uuid.UUID(uuidData).String(), Content: bsonResource["content"], ContentType: bsonResource["content-type"].(string), } return true, res, nil }
func (m *ApiClient) FQNameByUuid(id string) ([]string, error) { obj, err := m.db.GetByUuid(uuid.Parse(id)) if err != nil { return []string{}, err } return obj.GetFQName(), nil }
// Turns a string into a PodUniqueKey iff the string properly parses as a UUID func ToPodUniqueKey(podUniqueKeyStr string) (PodUniqueKey, error) { if uuid.Parse(podUniqueKeyStr) != nil { return PodUniqueKey(podUniqueKeyStr), nil } return "", InvalidUUID }
func parseDataRequest(request string, writ Writable) (uuidBytes uuid.UUID, startTime int64, endTime int64, pw uint8, extra1 string, extra2 string, success bool) { var args []string = strings.Split(string(request), ",") var err error success = false var w io.Writer if len(args) != 4 && len(args) != 5 && len(args) != 6 { w = writ.GetWriter() w.Write([]byte(fmt.Sprintf("Four, five, or six arguments are required; got %v", len(args)))) return } if len(args) == 6 { extra1 = args[4] extra2 = args[5] } else if len(args) == 5 { extra1 = args[4] } uuidBytes = uuid.Parse(args[0]) if uuidBytes == nil { w = writ.GetWriter() w.Write([]byte(fmt.Sprintf("Invalid UUID: got %v", args[0]))) return } var pwTemp int64 startTime, err = strconv.ParseInt(args[1], 10, 64) if err != nil { w = writ.GetWriter() w.Write([]byte(fmt.Sprintf("Could not interpret %v as an int64: %v", args[1], err))) return } endTime, err = strconv.ParseInt(args[2], 10, 64) if err != nil { w = writ.GetWriter() w.Write([]byte(fmt.Sprintf("Could not interpret %v as an int64: %v", args[2], err))) return } pwTemp, err = strconv.ParseInt(args[3], 10, 16) if err != nil { w = writ.GetWriter() w.Write([]byte(fmt.Sprintf("Could not interpret %v as an int16: %v", args[3], err))) return } pw = uint8(pwTemp) startTime = ((startTime >> pw) << pw) endTime = (((endTime >> pw) + 1) << pw) // we add one pointwidth to the endtime to simulate an inclusive endpoint success = true return }
// Executes the "info" command func execInfoCommand(c *cli.Context) error { if len(c.Args()) == 0 { return cli.NewExitError(errNoMinion.Error(), 64) } arg := c.Args()[0] minion := uuid.Parse(arg) if minion == nil { return cli.NewExitError(errInvalidUUID.Error(), 64) } klient := newEtcdMinionClientFromFlags(c) name, err := klient.MinionName(minion) if err != nil { return cli.NewExitError(err.Error(), 1) } lastseen, err := klient.MinionLastseen(minion) if err != nil { return cli.NewExitError(err.Error(), 1) } // Ignore errors about missing queue directory taskQueue, err := klient.MinionTaskQueue(minion) if err != nil { if eerr, ok := err.(client.Error); !ok || eerr.Code != client.ErrorCodeKeyNotFound { return cli.NewExitError(err.Error(), 1) } } // Ignore errors about missing log directory taskLog, err := klient.MinionTaskLog(minion) if err != nil { if eerr, ok := err.(client.Error); !ok || eerr.Code != client.ErrorCodeKeyNotFound { return cli.NewExitError(err.Error(), 1) } } // Ignore errors about missing classifier directory classifierKeys, err := klient.MinionClassifierKeys(minion) if err != nil { if eerr, ok := err.(client.Error); !ok || eerr.Code != client.ErrorCodeKeyNotFound { return cli.NewExitError(err.Error(), 1) } } table := uitable.New() table.MaxColWidth = 80 table.AddRow("Minion:", minion) table.AddRow("Name:", name) table.AddRow("Lastseen:", time.Unix(lastseen, 0)) table.AddRow("Queue:", len(taskQueue)) table.AddRow("Log:", len(taskLog)) table.AddRow("Classifiers:", len(classifierKeys)) fmt.Println(table) return nil }
func (m *ApiClient) DeleteByUuid(typename string, id string) error { obj, err := m.db.GetByUuid(uuid.Parse(id)) if err != nil { return err } // Ensure the object has no children and/or back_refs return m.db.Delete(obj) }
// DecodeUUID decodes a transit UUID into an instance of net/UUID func DecodeUUID(d Decoder, x interface{}) (interface{}, error) { s := x.(string) var u = uuid.Parse(s) if u == nil { return nil, &TransitError{Message: "Unable to parse uuid [" + s + "]"} } return u, nil }
func (self *ServiceID) UnmarshalJSON(b []byte) error { s := strings.Trim(string(b), "\"") self.UUID = uuid.Parse(s) if self.UUID == nil { return errors.New("Could not parse UUID") } return nil }
func (m *ApiClient) FindByUuid(typename string, id string) (contrail.IObject, error) { obj, err := m.db.GetByUuid(uuid.Parse(id)) if err != nil { return nil, err } m.interceptGet(obj) return obj, nil }
func getPod(name string) (*jetpack.Pod, error) { if id := uuid.Parse(name); id != nil { // Pod UUID return Host.GetPod(id) } // TODO: pod name return nil, ErrUsage }