예제 #1
0
파일: client.go 프로젝트: OSBI/juju
func (c *UnitFacadeClient) getResourceInfo(resourceName string) (resource.Resource, error) {
	var response private.ResourcesResult

	args := private.ListResourcesArgs{
		ResourceNames: []string{resourceName},
	}
	if err := c.FacadeCall("GetResourceInfo", &args, &response); err != nil {
		return resource.Resource{}, errors.Annotate(err, "could not get resource info")
	}
	if response.Error != nil {
		err, _ := common.RestoreError(response.Error)
		return resource.Resource{}, errors.Annotate(err, "request failed on server")
	}

	if len(response.Resources) != 1 {
		return resource.Resource{}, errors.New("got bad response from API server")
	}
	if response.Resources[0].Error != nil {
		err, _ := common.RestoreError(response.Error)
		return resource.Resource{}, errors.Annotate(err, "request failed for resource")
	}
	res, err := api.API2Resource(response.Resources[0].Resource)
	if err != nil {
		return resource.Resource{}, errors.Annotate(err, "got bad data from API server")
	}
	return res, nil
}
예제 #2
0
파일: helpers.go 프로젝트: bac/juju
// API2Result converts the API result to a payload.Result.
func API2Result(r PayloadResult) (payload.Result, error) {
	result := payload.Result{
		NotFound: r.NotFound,
	}

	id, err := API2ID(r.Tag)
	if err != nil {
		return result, errors.Trace(err)
	}
	result.ID = id

	if r.Payload != nil {
		pl, err := api.API2Payload(*r.Payload)
		if err != nil {
			return result, errors.Trace(err)
		}
		result.Payload = &pl
	}

	if r.Error != nil {
		result.Error = common.RestoreError(r.Error)
	}

	return result, nil
}
예제 #3
0
// AddPendingResources sends the provided resource info up to Juju
// without making it available yet.
func (c Client) AddPendingResources(args AddPendingResourcesArgs) (pendingIDs []string, err error) {
	apiArgs, err := api.NewAddPendingResourcesArgs(args.ServiceID, args.CharmID, args.CharmStoreMacaroon, args.Resources)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var result api.AddPendingResourcesResult
	if err := c.FacadeCall("AddPendingResources", &apiArgs, &result); err != nil {
		return nil, errors.Trace(err)
	}
	if result.Error != nil {
		err := common.RestoreError(result.Error)
		return nil, errors.Trace(err)
	}

	if len(result.PendingIDs) != len(args.Resources) {
		return nil, errors.Errorf("bad data from server: expected %d IDs, got %d", len(args.Resources), len(result.PendingIDs))
	}
	for i, id := range result.PendingIDs {
		if id == "" {
			return nil, errors.Errorf("bad data from server: got an empty ID for resource %q", args.Resources[i].Name)
		}
		// TODO(ericsnow) Do other validation?
	}

	return result.PendingIDs, nil
}
예제 #4
0
파일: lastsent.go 프로젝트: bac/juju
// GetLastSent makes a "GetLastSent" call on the facade and returns the
// results in the same order.
func (c LastSentClient) GetLastSent(ids []LastSentID) ([]LastSentResult, error) {
	var args params.LogForwardingGetLastSentParams
	args.IDs = make([]params.LogForwardingID, len(ids))
	for i, id := range ids {
		args.IDs[i] = params.LogForwardingID{
			ModelTag: id.Model.String(),
			Sink:     id.Sink,
		}
	}

	var apiResults params.LogForwardingGetLastSentResults
	err := c.caller.FacadeCall("GetLastSent", args, &apiResults)
	if err != nil {
		return nil, errors.Trace(err)
	}

	results := make([]LastSentResult, len(ids))
	for i, apiRes := range apiResults.Results {
		results[i] = LastSentResult{
			LastSentInfo: LastSentInfo{
				LastSentID: ids[i],
				RecordID:   apiRes.RecordID,
			},
			Error: common.RestoreError(apiRes.Error),
		}
		if apiRes.RecordTimestamp > 0 {
			results[i].RecordTimestamp = time.Unix(0, apiRes.RecordTimestamp)
		}
	}
	return results, nil
}
예제 #5
0
파일: lastsent.go 프로젝트: bac/juju
// SetLastSent makes a "SetLastSent" call on the facade and returns the
// results in the same order.
func (c LastSentClient) SetLastSent(reqs []LastSentInfo) ([]LastSentResult, error) {
	var args params.LogForwardingSetLastSentParams
	args.Params = make([]params.LogForwardingSetLastSentParam, len(reqs))
	for i, req := range reqs {
		args.Params[i] = params.LogForwardingSetLastSentParam{
			LogForwardingID: params.LogForwardingID{
				ModelTag: req.Model.String(),
				Sink:     req.Sink,
			},
			RecordID:        req.RecordID,
			RecordTimestamp: req.RecordTimestamp.UnixNano(),
		}
	}

	var apiResults params.ErrorResults
	err := c.caller.FacadeCall("SetLastSent", args, &apiResults)
	if err != nil {
		return nil, errors.Trace(err)
	}

	results := make([]LastSentResult, len(reqs))
	for i, apiRes := range apiResults.Results {
		results[i] = LastSentResult{
			LastSentInfo: reqs[i],
			Error:        common.RestoreError(apiRes.Error),
		}
	}
	return results, nil
}
예제 #6
0
파일: helpers.go 프로젝트: bac/juju
// APIResult2ServiceResources converts a ResourcesResult into a resource.ServiceResources.
func APIResult2ServiceResources(apiResult ResourcesResult) (resource.ServiceResources, error) {
	var result resource.ServiceResources

	if apiResult.Error != nil {
		// TODO(ericsnow) Return the resources too?
		err := common.RestoreError(apiResult.Error)
		return resource.ServiceResources{}, errors.Trace(err)
	}

	for _, apiRes := range apiResult.Resources {
		res, err := API2Resource(apiRes)
		if err != nil {
			// This could happen if the server is misbehaving
			// or non-conforming.
			// TODO(ericsnow) Aggregate errors?
			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
		}
		result.Resources = append(result.Resources, res)
	}

	for _, unitRes := range apiResult.UnitResources {
		tag, err := names.ParseUnitTag(unitRes.Tag)
		if err != nil {
			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
		}
		resNames := map[string]bool{}
		unitResources := resource.UnitResources{Tag: tag}
		for _, apiRes := range unitRes.Resources {
			res, err := API2Resource(apiRes)
			if err != nil {
				return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
			}
			resNames[res.Name] = true
			unitResources.Resources = append(unitResources.Resources, res)
		}
		if len(unitRes.DownloadProgress) > 0 {
			unitResources.DownloadProgress = make(map[string]int64)
			for resName, progress := range unitRes.DownloadProgress {
				if _, ok := resNames[resName]; !ok {
					err := errors.Errorf("got progress from unrecognized resource %q", resName)
					return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
				}
				unitResources.DownloadProgress[resName] = progress
			}
		}
		result.UnitResources = append(result.UnitResources, unitResources)
	}

	for _, chRes := range apiResult.CharmStoreResources {
		res, err := API2CharmResource(chRes)
		if err != nil {
			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
		}
		result.CharmStoreResources = append(result.CharmStoreResources, res)
	}

	return result, nil
}
예제 #7
0
func (s *errorsSuite) TestErrorTransform(c *gc.C) {
	for i, t := range errorTransformTests {
		c.Logf("running test %d: %T{%q}", i, t.err, t.err)
		err1, status := common.ServerErrorAndStatus(t.err)

		// Sanity check that ServerError returns the same thing.
		err2 := common.ServerError(t.err)
		c.Assert(err2, gc.DeepEquals, err1)
		c.Assert(status, gc.Equals, t.status)

		if t.err == nil {
			c.Assert(err1, gc.IsNil)
			c.Assert(status, gc.Equals, http.StatusOK)
			continue
		}
		c.Assert(err1.Message, gc.Equals, t.err.Error())
		c.Assert(err1.Code, gc.Equals, t.code)
		if t.helperFunc != nil {
			c.Assert(err1, jc.Satisfies, t.helperFunc)
		}

		// TODO(ericsnow) Remove this switch once the other error types are supported.
		switch t.code {
		case params.CodeHasAssignedUnits,
			params.CodeNoAddressSet,
			params.CodeUpgradeInProgress,
			params.CodeMachineHasAttachedStorage,
			params.CodeDischargeRequired:
			continue
		case params.CodeNotFound:
			if common.IsUnknownEnviromentError(t.err) {
				continue
			}
		case params.CodeOperationBlocked:
			// ServerError doesn't actually have a case for this code.
			continue
		}

		c.Logf("  checking restore (%#v)", err1)
		restored, ok := common.RestoreError(err1)
		if t.err == nil {
			c.Check(ok, jc.IsTrue)
			c.Check(restored, jc.ErrorIsNil)
		} else if t.code == "" {
			c.Check(ok, jc.IsFalse)
			c.Check(restored.Error(), gc.Equals, t.err.Error())
		} else {
			c.Check(ok, jc.IsTrue)
			// TODO(ericsnow) Use a stricter DeepEquals check.
			c.Check(errors.Cause(restored), gc.FitsTypeOf, t.err)
			c.Check(restored.Error(), gc.Equals, t.err.Error())
		}
	}
}
예제 #8
0
파일: helpers.go 프로젝트: OSBI/juju
// APIResult2ServiceResources converts a ResourcesResult into a resource.ServiceResources.
func APIResult2ServiceResources(apiResult ResourcesResult) (resource.ServiceResources, error) {
	var result resource.ServiceResources

	if apiResult.Error != nil {
		// TODO(ericsnow) Return the resources too?
		err, _ := common.RestoreError(apiResult.Error)
		return resource.ServiceResources{}, errors.Trace(err)
	}

	for _, apiRes := range apiResult.Resources {
		res, err := API2Resource(apiRes)
		if err != nil {
			// This could happen if the server is misbehaving
			// or non-conforming.
			// TODO(ericsnow) Aggregate errors?
			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
		}
		result.Resources = append(result.Resources, res)
	}

	for _, unitRes := range apiResult.UnitResources {
		tag, err := names.ParseUnitTag(unitRes.Tag)
		if err != nil {
			return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
		}
		unitResources := resource.UnitResources{Tag: tag}
		for _, apiRes := range unitRes.Resources {
			res, err := API2Resource(apiRes)
			if err != nil {
				return resource.ServiceResources{}, errors.Annotate(err, "got bad data from server")
			}
			unitResources.Resources = append(unitResources.Resources, res)
		}
		result.UnitResources = append(result.UnitResources, unitResources)
	}

	return result, nil
}
예제 #9
0
파일: lastsent_test.go 프로젝트: bac/juju
func (s *LastSentSuite) TestGetLastSent(c *gc.C) {
	stub := &testing.Stub{}
	caller := &stubFacadeCaller{stub: stub}
	caller.ReturnFacadeCallGet = params.LogForwardingGetLastSentResults{
		Results: []params.LogForwardingGetLastSentResult{{
			RecordID:        10,
			RecordTimestamp: 100,
		}, {
			RecordID:        20,
			RecordTimestamp: 200,
		}, {
			Error: common.ServerError(errors.NewNotFound(state.ErrNeverForwarded, "")),
		}},
	}
	client := logfwd.NewLastSentClient(caller.newFacadeCaller)
	model := "deadbeef-2f18-4fd2-967d-db9663db7bea"
	modelTag := names.NewModelTag(model)

	results, err := client.GetLastSent([]logfwd.LastSentID{{
		Model: modelTag,
		Sink:  "spam",
	}, {
		Model: modelTag,
		Sink:  "eggs",
	}, {
		Model: modelTag,
		Sink:  "ham",
	}})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(results, jc.DeepEquals, []logfwd.LastSentResult{{
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "spam",
			},
			RecordID:        10,
			RecordTimestamp: time.Unix(0, 100),
		},
	}, {
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "eggs",
			},
			RecordID:        20,
			RecordTimestamp: time.Unix(0, 200),
		},
	}, {
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "ham",
			},
		},
		Error: common.RestoreError(&params.Error{
			Message: `cannot find ID of the last forwarded record`,
			Code:    params.CodeNotFound,
		}),
	}})
	stub.CheckCallNames(c, "newFacadeCaller", "FacadeCall")
	stub.CheckCall(c, 0, "newFacadeCaller", "LogForwarding")
	stub.CheckCall(c, 1, "FacadeCall", "GetLastSent", params.LogForwardingGetLastSentParams{
		IDs: []params.LogForwardingID{{
			ModelTag: modelTag.String(),
			Sink:     "spam",
		}, {
			ModelTag: modelTag.String(),
			Sink:     "eggs",
		}, {
			ModelTag: modelTag.String(),
			Sink:     "ham",
		}},
	})
}
예제 #10
0
파일: lastsent_test.go 프로젝트: bac/juju
func (s *LastSentSuite) TestSetLastSent(c *gc.C) {
	stub := &testing.Stub{}
	caller := &stubFacadeCaller{stub: stub}
	apiError := common.ServerError(errors.New("<failed>"))
	caller.ReturnFacadeCallSet = params.ErrorResults{
		Results: []params.ErrorResult{{
			Error: nil,
		}, {
			Error: nil,
		}, {
			Error: apiError,
		}},
	}
	client := logfwd.NewLastSentClient(caller.newFacadeCaller)
	model := "deadbeef-2f18-4fd2-967d-db9663db7bea"
	modelTag := names.NewModelTag(model)

	results, err := client.SetLastSent([]logfwd.LastSentInfo{{
		LastSentID: logfwd.LastSentID{
			Model: modelTag,
			Sink:  "spam",
		},
		RecordID:        10,
		RecordTimestamp: time.Unix(0, 100),
	}, {
		LastSentID: logfwd.LastSentID{
			Model: modelTag,
			Sink:  "eggs",
		},
		RecordID:        20,
		RecordTimestamp: time.Unix(0, 200),
	}, {
		LastSentID: logfwd.LastSentID{
			Model: modelTag,
			Sink:  "ham",
		},
		RecordID:        15,
		RecordTimestamp: time.Unix(0, 150),
	}})
	c.Assert(err, jc.ErrorIsNil)

	c.Check(results, jc.DeepEquals, []logfwd.LastSentResult{{
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "spam",
			},
			RecordID:        10,
			RecordTimestamp: time.Unix(0, 100),
		},
	}, {
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "eggs",
			},
			RecordID:        20,
			RecordTimestamp: time.Unix(0, 200),
		},
	}, {
		LastSentInfo: logfwd.LastSentInfo{
			LastSentID: logfwd.LastSentID{
				Model: modelTag,
				Sink:  "ham",
			},
			RecordID:        15,
			RecordTimestamp: time.Unix(0, 150),
		},
		Error: common.RestoreError(apiError),
	}})
	stub.CheckCallNames(c, "newFacadeCaller", "FacadeCall")
	stub.CheckCall(c, 0, "newFacadeCaller", "LogForwarding")
	stub.CheckCall(c, 1, "FacadeCall", "SetLastSent", params.LogForwardingSetLastSentParams{
		Params: []params.LogForwardingSetLastSentParam{{
			LogForwardingID: params.LogForwardingID{
				ModelTag: modelTag.String(),
				Sink:     "spam",
			},
			RecordID:        10,
			RecordTimestamp: 100,
		}, {
			LogForwardingID: params.LogForwardingID{
				ModelTag: modelTag.String(),
				Sink:     "eggs",
			},
			RecordID:        20,
			RecordTimestamp: 200,
		}, {
			LogForwardingID: params.LogForwardingID{
				ModelTag: modelTag.String(),
				Sink:     "ham",
			},
			RecordID:        15,
			RecordTimestamp: 150,
		}},
	})
}