// NewConn returns a new Conn that uses the // given environment. The environment must have already // been bootstrapped. func NewConn(environ environs.Environ) (*Conn, error) { info, _, err := environ.StateInfo() if err != nil { return nil, err } password := environ.Config().AdminSecret() if password == "" { return nil, fmt.Errorf("cannot connect without admin-secret") } err = environs.CheckEnvironment(environ) if err != nil { return nil, err } info.Password = password opts := state.DefaultDialOpts() st, err := state.Open(info, opts) if errors.IsUnauthorizedError(err) { log.Noticef("juju: authorization error while connecting to state server; retrying") // We can't connect with the administrator password,; // perhaps this was the first connection and the // password has not been changed yet. info.Password = utils.PasswordHash(password) // We try for a while because we might succeed in // connecting to mongo before the state has been // initialized and the initial password set. for a := redialStrategy.Start(); a.Next(); { st, err = state.Open(info, opts) if !errors.IsUnauthorizedError(err) { break } } if err != nil { return nil, err } if err := st.SetAdminMongoPassword(password); err != nil { return nil, err } } else if err != nil { return nil, err } conn := &Conn{ Environ: environ, State: st, } if err := conn.updateSecrets(); err != nil { conn.Close() return nil, fmt.Errorf("unable to push secrets: %v", err) } return conn, nil }
func getMaybeSignedImageIdMetadata(baseURLs []string, indexPath string, ic *ImageConstraint, requireSigned bool) ([]*ImageMetadata, error) { var metadata []*ImageMetadata for _, baseURL := range baseURLs { indexRef, err := getIndexWithFormat(baseURL, indexPath, "index:1.0", requireSigned) if err != nil { if errors.IsNotFoundError(err) || errors.IsUnauthorizedError(err) { logger.Warningf("cannot load index %q/%q: %v", baseURL, indexPath, err) continue } return nil, err } metadata, err = indexRef.getLatestImageIdMetadataWithFormat(ic, "products:1.0", requireSigned) if err != nil { if errors.IsNotFoundError(err) { logger.Warningf("skipping index because of error getting latest metadata %q/%q: %v", baseURL, indexPath, err) continue } return nil, err } if len(metadata) > 0 { break } } return metadata, nil }
// OpenState tries to open the state using the given Conf. func (c *Conf) OpenState() (*state.State, error) { info := *c.StateInfo if info.Password != "" { st, err := state.Open(&info, state.DefaultDialOpts()) if err == nil { return st, nil } // TODO(rog) remove this fallback behaviour when // all initial connections are via the API. if !errors.IsUnauthorizedError(err) { return nil, err } } info.Password = c.OldPassword return state.Open(&info, state.DefaultDialOpts()) }
func getIndexWithFormat(baseURL, indexPath, format string, requireSigned bool) (*indexReference, error) { data, url, err := fetchData(baseURL, indexPath, requireSigned) if err != nil { if errors.IsNotFoundError(err) || errors.IsUnauthorizedError(err) { return nil, err } return nil, fmt.Errorf("cannot read index data, %v", err) } var indices indices err = json.Unmarshal(data, &indices) if err != nil { return nil, fmt.Errorf("cannot unmarshal JSON index metadata at URL %q: %v", url, err) } if indices.Format != format { return nil, fmt.Errorf("unexpected index file format %q, expected %q at URL %q", indices.Format, format, url) } return &indexReference{ indices: indices, baseURL: baseURL, }, nil }
// ServerError returns an error suitable for returning to an API // client, with an error code suitable for various kinds of errors // generated in packages outside the API. func ServerError(err error) *params.Error { if err == nil { return nil } code := singletonErrorCodes[err] switch { case code != "": case errors.IsUnauthorizedError(err): code = params.CodeUnauthorized case errors.IsNotFoundError(err): code = params.CodeNotFound case state.IsNotAssigned(err): code = params.CodeNotAssigned case state.IsHasAssignedUnitsError(err): code = params.CodeHasAssignedUnits default: code = params.ErrCode(err) } return ¶ms.Error{ Message: err.Error(), Code: code, } }
func getMaybeSignedImageIdMetadata(baseURLs []string, indexPath string, ic *ImageConstraint, requireSigned bool) ([]*ImageMetadata, error) { var metadata []*ImageMetadata for _, baseURL := range baseURLs { indexRef, err := getIndexWithFormat(baseURL, indexPath, "index:1.0", requireSigned) if err != nil { if errors.IsNotFoundError(err) || errors.IsUnauthorizedError(err) { continue } return nil, err } metadata, err = indexRef.getLatestImageIdMetadataWithFormat(ic, "products:1.0", requireSigned) if err != nil { if errors.IsNotFoundError(err) { continue } return nil, err } if len(metadata) > 0 { break } } return metadata, nil }