github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/common/errors.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package common 5 6 import ( 7 "fmt" 8 "io" 9 "strings" 10 11 "github.com/juju/errors" 12 "gopkg.in/macaroon-bakery.v2-unstable/httpbakery" 13 ) 14 15 func PermissionsMessage(writer io.Writer, command string) { 16 const ( 17 perm = "You do not have permission to %s." 18 grant = `You may ask an administrator to grant you access with "juju grant".` 19 ) 20 21 if command == "" { 22 command = "complete this operation" 23 } 24 fmt.Fprintf(writer, "\n%s\n%s\n\n", fmt.Sprintf(perm, command), grant) 25 } 26 27 // MaybeTermsAgreementError returns err as a *TermsAgreementError 28 // if it has a "terms agreement required" error code, otherwise 29 // it returns err unchanged. 30 func MaybeTermsAgreementError(err error) error { 31 const code = "term agreement required" 32 e, ok := errors.Cause(err).(*httpbakery.DischargeError) 33 if !ok || e.Reason == nil || e.Reason.Code != code { 34 return err 35 } 36 magicMarker := code + ":" 37 index := strings.LastIndex(e.Reason.Message, magicMarker) 38 if index == -1 { 39 return err 40 } 41 return &TermsRequiredError{strings.Fields(e.Reason.Message[index+len(magicMarker):])} 42 } 43 44 // TermsRequiredError is an error returned when agreement to terms is required. 45 type TermsRequiredError struct { 46 Terms []string 47 } 48 49 // Error implements error. 50 func (e *TermsRequiredError) Error() string { 51 return fmt.Sprintf("please agree to terms %q", strings.Join(e.Terms, " ")) 52 } 53 54 // UserErr returns an error containing a user-friendly message describing how 55 // to agree to required terms. 56 func (e *TermsRequiredError) UserErr() error { 57 terms := strings.Join(e.Terms, " ") 58 return errors.Wrap(e, 59 errors.Errorf(`Declined: some terms require agreement. Try: "juju agree %s"`, terms)) 60 }