コード例 #1
0
ファイル: provider.go プロジェクト: makyo/juju
// DetectRegions implements environs.CloudRegionDetector.
func (EnvironProvider) DetectRegions() ([]cloud.Region, error) {
	// If OS_REGION_NAME and OS_AUTH_URL are both set,
	// return return a region using them.
	creds := identity.CredentialsFromEnv()
	if creds.Region == "" {
		return nil, errors.NewNotFound(nil, "OS_REGION_NAME environment variable not set")
	}
	if creds.URL == "" {
		return nil, errors.NewNotFound(nil, "OS_AUTH_URL environment variable not set")
	}
	return []cloud.Region{{
		Name:     creds.Region,
		Endpoint: creds.URL,
	}}, nil
}
コード例 #2
0
ファイル: persistence_test.go プロジェクト: OSBI/juju
func (s *PersistenceSuite) TestNewResourcePendingResourceOpsNotFound(c *gc.C) {
	pendingID := "some-unique-ID-001"
	stored, expected := newResource(c, "a-service", "spam")
	stored.PendingID = pendingID
	doc := expected // a copy
	doc.DocID = pendingResourceID(stored.ID, pendingID)
	doc.PendingID = pendingID
	s.base.ReturnOne = doc
	notFound := errors.NewNotFound(nil, "")
	s.stub.SetErrors(nil, notFound)
	p := NewPersistence(s.base)

	ops, err := p.NewResolvePendingResourceOps(stored.ID, stored.PendingID)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c, "One", "One")
	s.stub.CheckCall(c, 0, "One", "resources", "resource#a-service/spam#pending-some-unique-ID-001", &doc)
	c.Check(ops, jc.DeepEquals, []txn.Op{{
		C:      "resources",
		Id:     doc.DocID,
		Assert: txn.DocExists,
		Remove: true,
	}, {
		C:      "resources",
		Id:     expected.DocID,
		Assert: txn.DocMissing,
		Insert: &expected,
	}})
}
コード例 #3
0
func (s *ResourcePersistenceSuite) TestSetResourceNotFound(c *gc.C) {
	applicationname := "a-application"
	res, doc := newPersistenceResource(c, applicationname, "spam")
	s.base.ReturnOne = doc
	expected := doc // a copy
	expected.StoragePath = ""
	p := NewResourcePersistence(s.base)
	notFound := errors.NewNotFound(nil, "")
	ignoredErr := errors.New("<never reached>")
	s.stub.SetErrors(notFound, nil, nil, nil, ignoredErr)

	err := p.SetResource(res.Resource)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c,
		"One",
		"Run",
		"ApplicationExistsOps",
		"RunTransaction",
	)
	s.stub.CheckCall(c, 3, "RunTransaction", []txn.Op{{
		C:      "resources",
		Id:     "resource#a-application/spam",
		Assert: txn.DocMissing,
		Insert: &expected,
	}, {
		C:      "application",
		Id:     "a-application",
		Assert: txn.DocExists,
	}})
}
コード例 #4
0
ファイル: environ.go プロジェクト: bac/juju
// cancelDeployment cancels a template deployment.
func (env *azureEnviron) cancelDeployment(name string) error {
	deploymentsClient := resources.DeploymentsClient{env.resources}
	logger.Debugf("- canceling deployment %q", name)
	var cancelResult autorest.Response
	if err := env.callAPI(func() (autorest.Response, error) {
		var err error
		cancelResult, err = deploymentsClient.Cancel(env.resourceGroup, name)
		return cancelResult, err
	}); err != nil {
		if cancelResult.Response != nil {
			switch cancelResult.StatusCode {
			case http.StatusNotFound:
				return errors.NewNotFound(err, fmt.Sprintf("deployment %q not found", name))
			case http.StatusConflict:
				if err, ok := errorutils.ServiceError(err); ok {
					if err.Code == serviceErrorCodeDeploymentCannotBeCancelled {
						// Deployments can only canceled while they're running.
						return nil
					}
				}
			}
		}
		return errors.Annotatef(err, "canceling deployment %q", name)
	}
	return nil
}
コード例 #5
0
ファイル: errors.go プロジェクト: exekias/juju
// RestoreError makes a best effort at converting the given error
// back into an error originally converted by ServerError(). If the
// error could not be converted then false is returned.
func RestoreError(err error) (error, bool) {
	err = errors.Cause(err)

	if apiErr, ok := err.(*params.Error); !ok {
		return err, false
	} else if apiErr == nil {
		return nil, true
	}
	if params.ErrCode(err) == "" {
		return err, false
	}
	msg := err.Error()

	if singleton, ok := singletonError(err); ok {
		return singleton, true
	}

	// TODO(ericsnow) Support the other error types handled by ServerError().
	switch {
	case params.IsCodeUnauthorized(err):
		return errors.NewUnauthorized(nil, msg), true
	case params.IsCodeNotFound(err):
		// TODO(ericsnow) UnknownModelError should be handled here too.
		// ...by parsing msg?
		return errors.NewNotFound(nil, msg), true
	case params.IsCodeAlreadyExists(err):
		return errors.NewAlreadyExists(nil, msg), true
	case params.IsCodeNotAssigned(err):
		return errors.NewNotAssigned(nil, msg), true
	case params.IsCodeHasAssignedUnits(err):
		// TODO(ericsnow) Handle state.HasAssignedUnitsError here.
		// ...by parsing msg?
		return err, false
	case params.IsCodeNoAddressSet(err):
		// TODO(ericsnow) Handle isNoAddressSetError here.
		// ...by parsing msg?
		return err, false
	case params.IsCodeNotProvisioned(err):
		return errors.NewNotProvisioned(nil, msg), true
	case params.IsCodeUpgradeInProgress(err):
		// TODO(ericsnow) Handle state.UpgradeInProgressError here.
		// ...by parsing msg?
		return err, false
	case params.IsCodeMachineHasAttachedStorage(err):
		// TODO(ericsnow) Handle state.HasAttachmentsError here.
		// ...by parsing msg?
		return err, false
	case params.IsCodeNotSupported(err):
		return errors.NewNotSupported(nil, msg), true
	case params.IsBadRequest(err):
		return errors.NewBadRequest(nil, msg), true
	case params.IsMethodNotAllowed(err):
		return errors.NewMethodNotAllowed(nil, msg), true
	case params.ErrCode(err) == params.CodeDischargeRequired:
		// TODO(ericsnow) Handle DischargeRequiredError here.
		return err, false
	default:
		return err, false
	}
}
コード例 #6
0
ファイル: bootstrap.go プロジェクト: makyo/juju
// getRegion returns the cloud.Region to use, based on the specified
// region name, and the region name selected if none was specified.
//
// If no region name is specified, and there is at least one region,
// we use the first region in the list.
//
// If no region name is specified, and there are no regions at all,
// then we synthesise a region from the cloud's endpoint information
// and just pass this on to the provider.
func getRegion(cloud *jujucloud.Cloud, cloudName, regionName string) (jujucloud.Region, error) {
	if len(cloud.Regions) == 0 {
		// The cloud does not specify regions, so assume
		// that the cloud provider does not have a concept
		// of regions, or has no pre-defined regions, and
		// defer validation to the provider.
		region := jujucloud.Region{
			regionName,
			cloud.Endpoint,
			cloud.StorageEndpoint,
		}
		return region, nil
	}
	if regionName == "" {
		// No region was specified, use the first region in the list.
		return cloud.Regions[0], nil
	}
	for _, region := range cloud.Regions {
		// Do a case-insensitive comparison
		if strings.EqualFold(region.Name, regionName) {
			return region, nil
		}
	}
	return jujucloud.Region{}, errors.NewNotFound(nil, fmt.Sprintf(
		"region %q in cloud %q not found (expected one of %q)\nalternatively, try %q",
		regionName, cloudName, cloudRegionNames(cloud), "juju update-clouds",
	))
}
コード例 #7
0
ファイル: credentials.go プロジェクト: kat-co/juju
func (c OpenstackCredentials) detectCredential() (*cloud.Credential, string, string, error) {
	creds := identity.CredentialsFromEnv()
	if creds.TenantName == "" {
		return nil, "", "", errors.NewNotFound(nil, "OS_TENANT_NAME environment variable not set")
	}
	if creds.User == "" {
		return nil, "", "", errors.NewNotFound(nil, "neither OS_USERNAME nor OS_ACCESS_KEY environment variable not set")
	}
	if creds.Secrets == "" {
		return nil, "", "", errors.NewNotFound(nil, "neither OS_PASSWORD nor OS_SECRET_KEY environment variable not set")
	}

	user, err := utils.LocalUsername()
	if err != nil {
		return nil, "", "", errors.Trace(err)
	}

	// If OS_USERNAME or NOVA_USERNAME is set, assume userpass.
	var credential cloud.Credential
	if os.Getenv("OS_USERNAME") != "" || os.Getenv("NOVA_USERNAME") != "" {
		user = creds.User
		credential = cloud.NewCredential(
			cloud.UserPassAuthType,
			map[string]string{
				credAttrUserName:   creds.User,
				credAttrPassword:   creds.Secrets,
				credAttrTenantName: creds.TenantName,
				credAttrDomainName: creds.DomainName,
			},
		)
	} else {
		credential = cloud.NewCredential(
			cloud.AccessKeyAuthType,
			map[string]string{
				credAttrAccessKey:  creds.User,
				credAttrSecretKey:  creds.Secrets,
				credAttrTenantName: creds.TenantName,
			},
		)
	}
	region := creds.Region
	if region == "" {
		region = "<unspecified>"
	}
	credential.Label = fmt.Sprintf("openstack region %q project %q user %q", region, creds.TenantName, user)
	return &credential, user, creds.Region, nil
}
コード例 #8
0
ファイル: raw.go プロジェクト: imoapps/juju
func convertRawAPIError(err error) error {
	if err2, ok := err.(*googleapi.Error); ok {
		if err2.Code == http.StatusNotFound {
			return errors.NewNotFound(err, "")
		}
	}
	return err
}
コード例 #9
0
ファイル: storage.go プロジェクト: jiasir/juju
func (s *JoyentStorage) Get(name string) (io.ReadCloser, error) {
	b, err := s.manta.GetObject(s.containerName, name)
	if err != nil {
		return nil, errors.NewNotFound(err, fmt.Sprintf("cannot find %s", name))
	}
	r := byteCloser{bytes.NewReader(b)}
	return r, nil
}
コード例 #10
0
ファイル: storage.go プロジェクト: jiasir/juju
// DeleteContainer deletes the named container from the storage account.
func (s *JoyentStorage) DeleteContainer(containerName string) error {
	err := s.manta.DeleteDirectory(containerName)
	if err == nil && strings.EqualFold(s.containerName, containerName) {
		s.madeContainer = false
	}
	if je.IsResourceNotFound(err) {
		return errors.NewNotFound(err, fmt.Sprintf("cannot delete %s, not found", containerName))
	}
	return err
}
コード例 #11
0
ファイル: state.go プロジェクト: AlexisBruemmer/juju
// VerifyService implements resource/state.RawState.
func (st rawState) VerifyService(id string) error {
	svc, err := st.base.Service(id)
	if err != nil {
		return errors.Trace(err)
	}
	if svc.Life() != corestate.Alive {
		return errors.NewNotFound(nil, fmt.Sprintf("service %q dying or dead", id))
	}
	return nil
}
コード例 #12
0
ファイル: modeluser.go プロジェクト: kat-co/juju
// removeModelUser removes a user from the database.
func (st *State) removeModelUser(user names.UserTag) error {
	ops := removeModelUserOps(st.ModelUUID(), user)
	err := st.runTransaction(ops)
	if err == txn.ErrAborted {
		err = errors.NewNotFound(nil, fmt.Sprintf("model user %q does not exist", user.Canonical()))
	}
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
コード例 #13
0
ファイル: controlleruser.go プロジェクト: bac/juju
// RemoveControllerUser removes a user from the database.
func (st *State) removeControllerUser(user names.UserTag) error {
	ops := removeControllerUserOps(st.ControllerUUID(), user)
	err := st.runTransaction(ops)
	if err == txn.ErrAborted {
		err = errors.NewNotFound(nil, fmt.Sprintf("controller user %q does not exist", user.Id()))
	}
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
コード例 #14
0
ファイル: config.go プロジェクト: AlexisBruemmer/juju
func (r *globalProviderRegistry) Provider(providerType string) (EnvironProvider, error) {
	if alias, ok := r.aliases[providerType]; ok {
		providerType = alias
	}
	p, ok := r.providers[providerType]
	if !ok {
		return nil, errors.NewNotFound(
			nil, fmt.Sprintf("no registered provider for %q", providerType),
		)
	}
	return p, nil
}
コード例 #15
0
ファイル: clouds.go プロジェクト: kat-co/juju
// RegionByName finds the region in the given slice with the
// specified name, with case folding.
func RegionByName(regions []Region, name string) (*Region, error) {
	for _, region := range regions {
		if !strings.EqualFold(region.Name, name) {
			continue
		}
		return &region, nil
	}
	return nil, errors.NewNotFound(nil, fmt.Sprintf(
		"region %q not found (expected one of %q)",
		name, RegionNames(regions),
	))
}
コード例 #16
0
ファイル: environ_vpc.go プロジェクト: bac/juju
// getVPCSubnetIDsForAvailabilityZone returns a sorted list of subnet IDs, which
// are both in the given vpcID and the given zoneName. If allowedSubnetIDs is
// not empty, the returned list will only contain IDs present there. Returns an
// error satisfying errors.IsNotFound() when no results match.
func getVPCSubnetIDsForAvailabilityZone(
	apiClient vpcAPIClient,
	vpcID, zoneName string,
	allowedSubnetIDs []string,
) ([]string, error) {
	allowedSubnets := set.NewStrings(allowedSubnetIDs...)
	vpc := &ec2.VPC{Id: vpcID}
	subnets, err := getVPCSubnets(apiClient, vpc)
	if err != nil && !isVPCNotUsableError(err) {
		return nil, errors.Annotatef(err, "cannot get VPC %q subnets", vpcID)
	} else if isVPCNotUsableError(err) {
		// We're reusing getVPCSubnets(), but not while validating a VPC
		// pre-bootstrap, so we should change vpcNotUsableError to a simple
		// NotFoundError.
		message := fmt.Sprintf("VPC %q has no subnets in AZ %q", vpcID, zoneName)
		return nil, errors.NewNotFound(err, message)
	}

	matchingSubnetIDs := set.NewStrings()
	for _, subnet := range subnets {
		if subnet.AvailZone != zoneName {
			logger.Infof("skipping subnet %q (in VPC %q): not in the chosen AZ %q", subnet.Id, vpcID, zoneName)
			continue
		}
		if !allowedSubnets.IsEmpty() && !allowedSubnets.Contains(subnet.Id) {
			logger.Infof("skipping subnet %q (in VPC %q, AZ %q): not matching spaces constraints", subnet.Id, vpcID, zoneName)
			continue
		}
		matchingSubnetIDs.Add(subnet.Id)
	}

	if matchingSubnetIDs.IsEmpty() {
		message := fmt.Sprintf("VPC %q has no subnets in AZ %q", vpcID, zoneName)
		return nil, errors.NewNotFound(nil, message)
	}

	sortedIDs := matchingSubnetIDs.SortedValues()
	logger.Infof("found %d subnets in VPC %q matching AZ %q and constraints: %v", len(sortedIDs), vpcID, zoneName, sortedIDs)
	return sortedIDs, nil
}
コード例 #17
0
func (s *ResourcePersistenceSuite) TestNewResourcePendingResourceOpsNotFound(c *gc.C) {
	pendingID := "some-unique-ID-001"
	stored, expected := newPersistenceResource(c, "a-application", "spam")
	stored.PendingID = pendingID
	doc := expected // a copy
	doc.DocID = pendingResourceID(stored.ID, pendingID)
	doc.PendingID = pendingID
	s.base.ReturnOne = doc
	notFound := errors.NewNotFound(nil, "")
	s.stub.SetErrors(nil, notFound)
	p := NewResourcePersistence(s.base)

	// TODO(macgreagoir) We need to keep using time.Now() for now, while we
	// have NewResolvePendingResourceOps returning LastPolled based on
	// timeNow(). lp:1558657
	lastPolled := time.Now().UTC().Round(time.Second)
	ops, err := p.NewResolvePendingResourceOps(stored.ID, stored.PendingID)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c, "One", "One")
	s.stub.CheckCall(c, 0, "One", "resources", "resource#a-application/spam#pending-some-unique-ID-001", &doc)

	csresourceDoc := expected
	csresourceDoc.DocID = "resource#a-application/spam#charmstore"
	csresourceDoc.Username = ""
	csresourceDoc.Timestamp = coretesting.ZeroTime()
	csresourceDoc.StoragePath = ""
	csresourceDoc.LastPolled = lastPolled

	res := ops[2].Insert.(*resourceDoc)
	res.LastPolled = res.LastPolled.Round(time.Second)

	c.Check(ops, jc.DeepEquals, []txn.Op{
		{
			C:      "resources",
			Id:     doc.DocID,
			Assert: txn.DocExists,
			Remove: true,
		}, {
			C:      "resources",
			Id:     expected.DocID,
			Assert: txn.DocMissing,
			Insert: &expected,
		},
		{
			C:      "resources",
			Id:     csresourceDoc.DocID,
			Assert: txn.DocMissing,
			Insert: &csresourceDoc,
		},
	})
}
コード例 #18
0
ファイル: utils.go プロジェクト: bac/juju
// deleteResource deletes a resource with the given name from the resource
// group, using the provided "Deleter". If the resource does not exist, an
// error satisfying errors.IsNotFound will be returned.
func deleteResource(callAPI callAPIFunc, deleter resourceDeleter, resourceGroup, name string) error {
	var result autorest.Response
	if err := callAPI(func() (autorest.Response, error) {
		var err error
		result, err = deleter.Delete(resourceGroup, name, nil)
		return result, err
	}); err != nil {
		if result.Response != nil && result.StatusCode == http.StatusNotFound {
			return errors.NewNotFound(err, fmt.Sprintf("resource %q not found", name))
		}
		return errors.Annotate(err, "canceling deployment")
	}
	return nil
}
コード例 #19
0
func (s *ResourcePersistenceSuite) TestSetUnitResourceNotFound(c *gc.C) {
	applicationname := "a-application"
	unitname := "a-application/0"
	res, _ := newPersistenceUnitResource(c, applicationname, unitname, "eggs")
	p := NewResourcePersistence(s.base)
	notFound := errors.NewNotFound(nil, "")
	s.stub.SetErrors(notFound)

	err := p.SetUnitResource("a-application/0", res)

	s.stub.CheckCallNames(c, "One")
	c.Check(err, jc.Satisfies, errors.IsNotFound)
	c.Check(err, gc.ErrorMatches, `resource "eggs" not found`)
}
コード例 #20
0
func (s *ResourcePersistenceSuite) TestNewResourcePendingResourceOpsNotFound(c *gc.C) {
	pendingID := "some-unique-ID-001"
	stored, expected := newPersistenceResource(c, "a-service", "spam")
	stored.PendingID = pendingID
	doc := expected // a copy
	doc.DocID = pendingResourceID(stored.ID, pendingID)
	doc.PendingID = pendingID
	s.base.ReturnOne = doc
	notFound := errors.NewNotFound(nil, "")
	s.stub.SetErrors(nil, notFound)
	p := NewResourcePersistence(s.base)

	lastPolled := time.Now().UTC().Round(time.Second)
	ops, err := p.NewResolvePendingResourceOps(stored.ID, stored.PendingID)
	c.Assert(err, jc.ErrorIsNil)

	s.stub.CheckCallNames(c, "One", "One")
	s.stub.CheckCall(c, 0, "One", "resources", "resource#a-service/spam#pending-some-unique-ID-001", &doc)

	csresourceDoc := expected
	csresourceDoc.DocID = "resource#a-service/spam#charmstore"
	csresourceDoc.Username = ""
	csresourceDoc.Timestamp = time.Time{}
	csresourceDoc.StoragePath = ""
	csresourceDoc.LastPolled = lastPolled

	res := ops[2].Insert.(*resourceDoc)
	res.LastPolled = res.LastPolled.Round(time.Second)

	c.Check(ops, jc.DeepEquals, []txn.Op{
		{
			C:      "resources",
			Id:     doc.DocID,
			Assert: txn.DocExists,
			Remove: true,
		}, {
			C:      "resources",
			Id:     expected.DocID,
			Assert: txn.DocMissing,
			Insert: &expected,
		},
		{
			C:      "resources",
			Id:     csresourceDoc.DocID,
			Assert: txn.DocMissing,
			Insert: &csresourceDoc,
		},
	})
}
コード例 #21
0
ファイル: modeluser.go プロジェクト: makyo/juju
// RemoveModelUser removes a user from the database.
func (st *State) RemoveModelUser(user names.UserTag) error {
	ops := []txn.Op{{
		C:      modelUsersC,
		Id:     modelUserID(user),
		Assert: txn.DocExists,
		Remove: true,
	}}
	err := st.runTransaction(ops)
	if err == txn.ErrAborted {
		err = errors.NewNotFound(nil, fmt.Sprintf("model user %q does not exist", user.Canonical()))
	}
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
コード例 #22
0
ファイル: envuser.go プロジェクト: claudiu-coblis/juju
// RemoveEnvironmentUser removes a user from the database.
func (st *State) RemoveEnvironmentUser(user names.UserTag) error {
	ops := []txn.Op{{
		C:      envUsersC,
		Id:     envUserID(user),
		Assert: txn.DocExists,
		Remove: true,
	}}
	err := st.runTransaction(ops)
	if err == txn.ErrAborted {
		err = errors.NewNotFound(err, fmt.Sprintf("env user %q does not exist", user.Username()))
	}
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
コード例 #23
0
ファイル: addmodel.go プロジェクト: kat-co/juju
func defaultCloud(cloudClient CloudAPI) (names.CloudTag, jujucloud.Cloud, error) {
	cloudTag, err := cloudClient.DefaultCloud()
	if err != nil {
		if params.IsCodeNotFound(err) {
			return names.CloudTag{}, jujucloud.Cloud{}, errors.NewNotFound(nil, `
there is no default cloud defined, please specify one using:

    juju add-model [flags] <model-name> cloud[/region]`[1:])
		}
		return names.CloudTag{}, jujucloud.Cloud{}, errors.Trace(err)
	}
	cloud, err := cloudClient.Cloud(cloudTag)
	if err != nil {
		return names.CloudTag{}, jujucloud.Cloud{}, errors.Trace(err)
	}
	return cloudTag, cloud, nil
}
コード例 #24
0
ファイル: environ.go プロジェクト: bac/juju
func (env *azureEnviron) getStorageAccountLocked(refresh bool) (*storage.Account, error) {
	if !refresh && env.storageAccount != nil {
		return env.storageAccount, nil
	}
	client := storage.AccountsClient{env.storage}
	var account storage.Account
	if err := env.callAPI(func() (autorest.Response, error) {
		var err error
		account, err = client.GetProperties(env.resourceGroup, env.storageAccountName)
		return account.Response, err
	}); err != nil {
		if account.Response.Response != nil && account.Response.StatusCode == http.StatusNotFound {
			return nil, errors.NewNotFound(err, fmt.Sprintf("storage account not found"))
		}
		return nil, errors.Annotate(err, "getting storage account")
	}
	env.storageAccount = &account
	return env.storageAccount, nil
}
コード例 #25
0
ファイル: storage.go プロジェクト: kapilt/juju
// Get implements storage.StorageReader.Get.
func (s *SSHStorage) Get(name string) (io.ReadCloser, error) {
	logger.Debugf("getting %q from storage", name)
	path, err := s.path(name)
	if err != nil {
		return nil, err
	}
	out, err := s.runf(flockShared, "base64 < %s", utils.ShQuote(path))
	if err != nil {
		err := err.(SSHStorageError)
		if strings.Contains(err.Output, "No such file") {
			return nil, errors.NewNotFound(err, "")
		}
		return nil, err
	}
	decoded, err := base64.StdEncoding.DecodeString(out)
	if err != nil {
		return nil, err
	}
	return ioutil.NopCloser(bytes.NewBuffer(decoded)), nil
}
コード例 #26
0
ファイル: storage.go プロジェクト: bac/juju
// getStorageAccountKey returns the key for the storage account.
func getStorageAccountKey(
	callAPI callAPIFunc,
	client armstorage.AccountsClient,
	resourceGroup, accountName string,
) (*armstorage.AccountKey, error) {
	logger.Debugf("getting keys for storage account %q", accountName)
	var listKeysResult armstorage.AccountListKeysResult
	if err := callAPI(func() (autorest.Response, error) {
		var err error
		listKeysResult, err = client.ListKeys(resourceGroup, accountName)
		return listKeysResult.Response, err
	}); err != nil {
		if listKeysResult.Response.Response != nil && listKeysResult.StatusCode == http.StatusNotFound {
			return nil, errors.NewNotFound(err, "storage account keys not found")
		}
		return nil, errors.Annotate(err, "listing storage account keys")
	}
	if listKeysResult.Keys == nil {
		return nil, errors.NotFoundf("storage account keys")
	}

	// We need a storage key with full permissions.
	var fullKey *armstorage.AccountKey
	for _, key := range *listKeysResult.Keys {
		logger.Debugf("storage account key: %#v", key)
		// At least some of the time, Azure returns the permissions
		// in title-case, which does not match the constant.
		if strings.ToUpper(string(key.Permissions)) != string(armstorage.FULL) {
			continue
		}
		fullKey = &key
		break
	}
	if fullKey == nil {
		return nil, errors.NotFoundf(
			"storage account key with %q permission",
			armstorage.FULL,
		)
	}
	return fullKey, nil
}
コード例 #27
0
ファイル: credentials.go プロジェクト: bac/juju
func (environProviderCredentials) detectEnvCredentials() (*cloud.CloudCredential, error) {
	auth, err := aws.EnvAuth()
	if err != nil {
		return nil, errors.NewNotFound(err, "credentials not found")
	}
	accessKeyCredential := cloud.NewCredential(
		cloud.AccessKeyAuthType,
		map[string]string{
			"access-key": auth.AccessKey,
			"secret-key": auth.SecretKey,
		},
	)
	user, err := utils.LocalUsername()
	if err != nil {
		return nil, errors.Trace(err)
	}
	accessKeyCredential.Label = fmt.Sprintf("aws credential %q", user)
	return &cloud.CloudCredential{
		AuthCredentials: map[string]cloud.Credential{
			user: accessKeyCredential,
		}}, nil
}
コード例 #28
0
ファイル: filestorage.go プロジェクト: bac/juju
// Get implements storage.StorageReader.Get.
func (f *fileStorageReader) Get(name string) (io.ReadCloser, error) {
	if isInternalPath(name) {
		return nil, &os.PathError{
			Op:   "Get",
			Path: name,
			Err:  os.ErrNotExist,
		}
	}
	filename := f.fullPath(name)
	fi, err := os.Stat(filename)
	if err != nil {
		if os.IsNotExist(err) {
			err = errors.NewNotFound(err, "")
		}
		return nil, err
	} else if fi.IsDir() {
		return nil, errors.NotFoundf("no such file with name %q", name)
	}
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	return file, nil
}
コード例 #29
0
ファイル: modelmanager.go プロジェクト: bac/juju
// CreateModel creates a new model using the account and
// model config specified in the args.
func (m *ModelManagerAPI) CreateModel(args params.ModelCreateArgs) (params.ModelInfo, error) {
	result := params.ModelInfo{}
	canAddModel, err := m.authorizer.HasPermission(permission.AddModelAccess, m.state.ControllerTag())
	if err != nil {
		return result, errors.Trace(err)
	}
	if !canAddModel {
		return result, common.ErrPerm
	}

	// Get the controller model first. We need it both for the state
	// server owner and the ability to get the config.
	controllerModel, err := m.state.ControllerModel()
	if err != nil {
		return result, errors.Trace(err)
	}

	ownerTag, err := names.ParseUserTag(args.OwnerTag)
	if err != nil {
		return result, errors.Trace(err)
	}

	var cloudTag names.CloudTag
	cloudRegionName := args.CloudRegion
	if args.CloudTag != "" {
		var err error
		cloudTag, err = names.ParseCloudTag(args.CloudTag)
		if err != nil {
			return result, errors.Trace(err)
		}
	} else {
		cloudTag = names.NewCloudTag(controllerModel.Cloud())
	}
	if cloudRegionName == "" && cloudTag.Id() == controllerModel.Cloud() {
		cloudRegionName = controllerModel.CloudRegion()
	}

	cloud, err := m.state.Cloud(cloudTag.Id())
	if err != nil {
		if errors.IsNotFound(err) && args.CloudTag != "" {
			// A cloud was specified, and it was not found.
			// Annotate the error with the supported clouds.
			clouds, err := m.state.Clouds()
			if err != nil {
				return result, errors.Trace(err)
			}
			cloudNames := make([]string, 0, len(clouds))
			for tag := range clouds {
				cloudNames = append(cloudNames, tag.Id())
			}
			sort.Strings(cloudNames)
			return result, errors.NewNotFound(err, fmt.Sprintf(
				"cloud %q not found, expected one of %q",
				cloudTag.Id(), cloudNames,
			))
		}
		return result, errors.Annotate(err, "getting cloud definition")
	}

	var cloudCredentialTag names.CloudCredentialTag
	if args.CloudCredentialTag != "" {
		var err error
		cloudCredentialTag, err = names.ParseCloudCredentialTag(args.CloudCredentialTag)
		if err != nil {
			return result, errors.Trace(err)
		}
	} else {
		if ownerTag == controllerModel.Owner() {
			cloudCredentialTag, _ = controllerModel.CloudCredential()
		} else {
			// TODO(axw) check if the user has one and only one
			// cloud credential, and if so, use it? For now, we
			// require the user to specify a credential unless
			// the cloud does not require one.
			var hasEmpty bool
			for _, authType := range cloud.AuthTypes {
				if authType != jujucloud.EmptyAuthType {
					continue
				}
				hasEmpty = true
				break
			}
			if !hasEmpty {
				return result, errors.NewNotValid(nil, "no credential specified")
			}
		}
	}

	var credential *jujucloud.Credential
	if cloudCredentialTag != (names.CloudCredentialTag{}) {
		credentialValue, err := m.state.CloudCredential(cloudCredentialTag)
		if err != nil {
			return result, errors.Annotate(err, "getting credential")
		}
		credential = &credentialValue
	}

	cloudSpec, err := environs.MakeCloudSpec(cloud, cloudTag.Id(), cloudRegionName, credential)
	if err != nil {
		return result, errors.Trace(err)
	}

	controllerCfg, err := m.state.ControllerConfig()
	if err != nil {
		return result, errors.Trace(err)
	}

	newConfig, err := m.newModelConfig(cloudSpec, args, controllerModel)
	if err != nil {
		return result, errors.Annotate(err, "failed to create config")
	}

	// Create the Environ.
	env, err := environs.New(environs.OpenParams{
		Cloud:  cloudSpec,
		Config: newConfig,
	})
	if err != nil {
		return result, errors.Annotate(err, "failed to open environ")
	}
	if err := env.Create(environs.CreateParams{
		ControllerUUID: controllerCfg.ControllerUUID(),
	}); err != nil {
		return result, errors.Annotate(err, "failed to create environ")
	}
	storageProviderRegistry := stateenvirons.NewStorageProviderRegistry(env)

	// NOTE: check the agent-version of the config, and if it is > the current
	// version, it is not supported, also check existing tools, and if we don't
	// have tools for that version, also die.
	model, st, err := m.state.NewModel(state.ModelArgs{
		CloudName:       cloudTag.Id(),
		CloudRegion:     cloudRegionName,
		CloudCredential: cloudCredentialTag,
		Config:          newConfig,
		Owner:           ownerTag,
		StorageProviderRegistry: storageProviderRegistry,
	})
	if err != nil {
		return result, errors.Annotate(err, "failed to create new model")
	}
	defer st.Close()

	return m.getModelInfo(model.ModelTag())
}
コード例 #30
0
ファイル: tools.go プロジェクト: ktsakalozos/juju
func convertToolsError(err *error) {
	if isToolsError(*err) {
		*err = errors.NewNotFound(*err, "")
	}
}