func (c *SetConstraintsCommand) Init(args []string) (err error) { if c.ServiceName != "" && !names.IsValidService(c.ServiceName) { return fmt.Errorf("invalid service name %q", c.ServiceName) } c.Constraints, err = constraints.Parse(args...) return err }
// Run implements cmd.Command.Run. func (c *ShowServiceCommand) Run(ctx *cmd.Context) error { apiclient, err := c.deps.NewClient(c) if err != nil { return errors.Annotatef(err, "can't connect to %s", c.ConnectionName()) } defer apiclient.Close() var unit string var service string if names.IsValidService(c.target) { service = c.target } else { service, err = names.UnitService(c.target) if err != nil { return errors.Errorf("%q is neither a service nor a unit", c.target) } unit = c.target } vals, err := apiclient.ListResources([]string{service}) if err != nil { return errors.Trace(err) } if len(vals) != 1 { return errors.Errorf("bad data returned from server") } v := vals[0] if unit == "" { return c.formatServiceResources(ctx, v) } return c.formatUnitResources(ctx, unit, service, v) }
// Rescale requests that all supplied service names be rescaled to // their minimum configured sizes. It returns the first error it // encounters. func (api *API) Rescale(services []string) error { args := params.Entities{ Entities: make([]params.Entity, len(services)), } for i, service := range services { if !names.IsValidService(service) { return errors.NotValidf("service name %q", service) } tag := names.NewServiceTag(service) args.Entities[i].Tag = tag.String() } var results params.ErrorResults err := api.caller.FacadeCall("Rescale", args, &results) if err != nil { return errors.Trace(err) } for _, result := range results.Results { if result.Error != nil { if err == nil { err = result.Error } else { logger.Errorf("additional rescale error: %v", err) } } } return errors.Trace(err) }
// NewAddPendingResourcesArgs returns the arguments for the // AddPendingResources API endpoint. func NewAddPendingResourcesArgs(serviceID string, chID charmstore.CharmID, csMac *macaroon.Macaroon, resources []charmresource.Resource) (AddPendingResourcesArgs, error) { var args AddPendingResourcesArgs if !names.IsValidService(serviceID) { return args, errors.Errorf("invalid service %q", serviceID) } tag := names.NewServiceTag(serviceID).String() var apiResources []CharmResource for _, res := range resources { if err := res.Validate(); err != nil { return args, errors.Trace(err) } apiRes := CharmResource2API(res) apiResources = append(apiResources, apiRes) } args.Tag = tag args.Resources = apiResources if chID.URL != nil { args.URL = chID.URL.String() args.Channel = string(chID.Channel) args.CharmStoreMacaroon = csMac } return args, nil }
func (c *GetConstraintsCommand) Init(args []string) error { if len(args) > 0 { if !names.IsValidService(args[0]) { return fmt.Errorf("invalid service name %q", args[0]) } c.ServiceName, args = args[0], args[1:] } return cmd.CheckEmpty(args) }
func (c *removeServiceCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no service specified") } if !names.IsValidService(args[0]) { return fmt.Errorf("invalid service name %q", args[0]) } c.ServiceName, args = args[0], args[1:] return cmd.CheckEmpty(args) }
func (c *serviceGetConstraintsCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no service name specified") } if !names.IsValidService(args[0]) { return fmt.Errorf("invalid service name %q", args[0]) } c.ServiceName = args[0] return nil }
// validate returns an error if any fields are invalid or missing. func (b block) validate() error { if !names.IsValidService(b.serviceName) { return errors.Errorf("invalid service name %q", b.serviceName) } if b.unblock == nil { return errors.New("missing unblock channel") } if b.abort == nil { return errors.New("missing abort channel") } return nil }
func (f *fakeConstraintsClient) GetServiceConstraints(name string) (constraints.Value, error) { if !names.IsValidService(name) { return constraints.Value{}, errors.Errorf("%q is not a valid service name", name) } cons, ok := f.servCons[name] if !ok { return constraints.Value{}, errors.NotFoundf("service %q", name) } return cons, nil }
func (c *serviceSetConstraintsCommand) Init(args []string) (err error) { if len(args) == 0 { return fmt.Errorf("no service name specified") } if !names.IsValidService(args[0]) { return fmt.Errorf("invalid service name %q", args[0]) } c.ServiceName, args = args[0], args[1:] c.Constraints, err = constraints.Parse(args...) return err }
// Init implements cmd.Command. func (c *setPlanCommand) Init(args []string) error { if len(args) < 2 { return errors.New("need to specify plan uuid and service name") } serviceName := args[0] if !names.IsValidService(serviceName) { return errors.Errorf("invalid service name %q", serviceName) } c.Plan = args[1] c.Service = serviceName return c.ModelCommandBase.Init(args[2:]) }
// Service returns a service state by name. func (st *State) Service(name string) (service *Service, err error) { if !names.IsValidService(name) { return nil, fmt.Errorf("%q is not a valid service name", name) } sdoc := &serviceDoc{} sel := bson.D{{"_id", name}} err = st.services.Find(sel).One(sdoc) if err == mgo.ErrNotFound { return nil, errors.NotFoundf("service %q", name) } if err != nil { return nil, fmt.Errorf("cannot get service %q: %v", name, err) } return newService(st, sdoc), nil }
// Init validates the service name and any other options. func (c *DefinedCommand) Init(args []string) error { switch len(args) { case 0: return errors.New("no service name specified") case 1: svcName := args[0] if !names.IsValidService(svcName) { return errors.Errorf("invalid service name %q", svcName) } c.serviceTag = names.NewServiceTag(svcName) return nil default: return cmd.CheckEmpty(args[1:]) } }
// validate returns an error if any fields are invalid or missing. func (c check) validate() error { if !names.IsValidService(c.serviceName) { return errors.Errorf("invalid service name %q", c.serviceName) } if !names.IsValidUnit(c.unitName) { return errors.Errorf("invalid unit name %q", c.unitName) } if c.response == nil { return errors.New("missing response channel") } if c.abort == nil { return errors.New("missing abort channel") } return nil }
// Init reads and verifies the cli arguments for the collectMetricsCommand func (c *collectMetricsCommand) Init(args []string) error { if len(args) == 0 { return errors.New("you need to specify a unit or service.") } if names.IsValidUnit(args[0]) { c.units = []string{args[0]} } else if names.IsValidService(args[0]) { c.services = []string{args[0]} } else { return errors.Errorf("%q is not a valid unit or service", args[0]) } if err := cmd.CheckEmpty(args[1:]); err != nil { return errors.Errorf("unknown command line arguments: " + strings.Join(args, ",")) } return nil }
func (c *deployCommand) Init(args []string) error { switch len(args) { case 2: if !names.IsValidService(args[1]) { return fmt.Errorf("invalid service name %q", args[1]) } c.ServiceName = args[1] fallthrough case 1: c.CharmOrBundle = args[0] case 0: return errors.New("no charm or bundle specified") default: return cmd.CheckEmpty(args[2:]) } return c.UnitCommandBase.Init(args) }
func (f *fakeConstraintsClient) SetServiceConstraints(name string, cons constraints.Value) error { if f.err != nil { return f.err } if !names.IsValidService(name) { return errors.Errorf("%q is not a valid service name", name) } _, ok := f.servCons[name] if !ok { return errors.NotFoundf("service %q", name) } f.servCons[name] = cons return nil }
func (c *UpgradeCharmCommand) Init(args []string) error { switch len(args) { case 1: if !names.IsValidService(args[0]) { return fmt.Errorf("invalid service name %q", args[0]) } c.ServiceName = args[0] case 0: return fmt.Errorf("no service specified") default: return cmd.CheckEmpty(args[1:]) } if c.SwitchURL != "" && c.Revision != -1 { return fmt.Errorf("--switch and --revision are mutually exclusive") } return nil }
func (c *RunCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no commands specified") } c.commands, args = args[0], args[1:] if c.all { if len(c.machines) != 0 { return fmt.Errorf("You cannot specify --all and individual machines") } if len(c.services) != 0 { return fmt.Errorf("You cannot specify --all and individual services") } if len(c.units) != 0 { return fmt.Errorf("You cannot specify --all and individual units") } } else { if len(c.machines) == 0 && len(c.services) == 0 && len(c.units) == 0 { return fmt.Errorf("You must specify a target, either through --all, --machine, --service or --unit") } } var nameErrors []string for _, machineId := range c.machines { if !names.IsValidMachine(machineId) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid machine id", machineId)) } } for _, service := range c.services { if !names.IsValidService(service) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid service name", service)) } } for _, unit := range c.units { if !names.IsValidUnit(unit) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid unit name", unit)) } } if len(nameErrors) > 0 { return fmt.Errorf("The following run targets are not valid:\n%s", strings.Join(nameErrors, "\n")) } return cmd.CheckEmpty(args) }
// Init reads and verifies the cli arguments for the SetMeterStatusCommand func (c *SetMeterStatusCommand) Init(args []string) error { if len(args) != 2 { return errors.New("you need to specify an entity (service or unit) and a status") } if names.IsValidUnit(args[0]) { c.Tag = names.NewUnitTag(args[0]) } else if names.IsValidService(args[0]) { c.Tag = names.NewServiceTag(args[0]) } else { return errors.Errorf("%q is not a valid unit or service", args[0]) } c.Status = args[1] if err := cmd.CheckEmpty(args[2:]); err != nil { return errors.Errorf("unknown command line arguments: " + strings.Join(args, ",")) } return nil }
// NewListResourcesArgs returns the arguments for the ListResources endpoint. func NewListResourcesArgs(services []string) (ListResourcesArgs, error) { var args ListResourcesArgs var errs []error for _, service := range services { if !names.IsValidService(service) { err := errors.Errorf("invalid service %q", service) errs = append(errs, err) continue } args.Entities = append(args.Entities, params.Entity{ Tag: names.NewServiceTag(service).String(), }) } if err := resolveErrors(errs); err != nil { return args, errors.Trace(err) } return args, nil }
// NewUploadRequest generates a new upload request for the given resource. func NewUploadRequest(service, name string, r io.ReadSeeker) (UploadRequest, error) { if !names.IsValidService(service) { return UploadRequest{}, errors.Errorf("invalid service %q", service) } content, err := resource.GenerateContent(r) if err != nil { return UploadRequest{}, errors.Trace(err) } ur := UploadRequest{ Service: service, Name: name, Size: content.Size, Fingerprint: content.Fingerprint, } return ur, nil }
func (s *serviceSuite) TestServiceNameFormats(c *gc.C) { assertService := func(s string, expect bool) { c.Assert(names.IsValidService(s), gc.Equals, expect) // Check that anything that is considered a valid service name // is also (in)valid if a(n) (in)valid unit designator is added // to it. c.Assert(names.IsValidUnit(s+"/0"), gc.Equals, expect) c.Assert(names.IsValidUnit(s+"/99"), gc.Equals, expect) c.Assert(names.IsValidUnit(s+"/-1"), gc.Equals, false) c.Assert(names.IsValidUnit(s+"/blah"), gc.Equals, false) c.Assert(names.IsValidUnit(s+"/"), gc.Equals, false) } for i, test := range serviceNameTests { c.Logf("test %d: %q", i, test.pattern) assertService(test.pattern, test.valid) } }
func (c *DeployCommand) Init(args []string) error { switch len(args) { case 2: if !names.IsValidService(args[1]) { return fmt.Errorf("invalid service name %q", args[1]) } c.ServiceName = args[1] fallthrough case 1: if _, err := charm.InferURL(args[0], "fake"); err != nil { return fmt.Errorf("invalid charm name %q", args[0]) } c.CharmName = args[0] case 0: return errors.New("no charm specified") default: return cmd.CheckEmpty(args[2:]) } return c.UnitCommandBase.Init(args) }
func (c *DeployCommand) Init(args []string) error { if c.Force && c.Series == "" && c.PlacementSpec == "" { return errors.New("--force is only used with --series") } switch len(args) { case 2: if !names.IsValidService(args[1]) { return fmt.Errorf("invalid service name %q", args[1]) } c.ServiceName = args[1] fallthrough case 1: c.CharmOrBundle = args[0] case 0: return errors.New("no charm or bundle specified") default: return cmd.CheckEmpty(args[2:]) } return c.UnitCommandBase.Init(args) }
// NewAddPendingResourcesArgs returns the arguments for the // AddPendingResources API endpoint. func NewAddPendingResourcesArgs(serviceID string, resources []charmresource.Resource) (AddPendingResourcesArgs, error) { var args AddPendingResourcesArgs if !names.IsValidService(serviceID) { return args, errors.Errorf("invalid service %q", serviceID) } tag := names.NewServiceTag(serviceID).String() var apiResources []CharmResource for _, res := range resources { if err := res.Validate(); err != nil { return args, errors.Trace(err) } apiRes := CharmResource2API(res) apiResources = append(apiResources, apiRes) } args.Tag = tag args.Resources = apiResources return args, nil }
// Validate checks the AuthorizationRequest for errors. func (s AuthorizationRequest) Validate() error { if !utils.IsValidUUIDString(s.EnvironmentUUID) { return errors.Errorf("invalid environment UUID: %q", s.EnvironmentUUID) } if s.ServiceName == "" { return errors.New("undefined service name") } if !names.IsValidService(s.ServiceName) { return errors.Errorf("invalid service name: %q", s.ServiceName) } if s.CharmURL == "" { return errors.New("undefined charm url") } if !names.IsValidCharm(s.CharmURL) { return errors.Errorf("invalid charm url: %q", s.CharmURL) } if s.PlanURL == "" { return errors.Errorf("undefined plan url") } return nil }
// CheckLease is part of the lease.Secretary interface. func (leadershipSecretary) CheckLease(name string) error { if !names.IsValidService(name) { return errors.NewNotValid(nil, "not a service name") } return nil }
// AddService creates a new service, running the supplied charm, with the // supplied name (which must be unique). If the charm defines peer relations, // they will be created automatically. func (st *State) AddService(name, ownerTag string, ch *Charm, networks []string) (service *Service, err error) { defer errors.Maskf(&err, "cannot add service %q", name) tag, err := names.ParseUserTag(ownerTag) if err != nil { return nil, fmt.Errorf("Invalid ownertag %s: %v", ownerTag, err) } // Sanity checks. if !names.IsValidService(name) { return nil, fmt.Errorf("invalid name") } if ch == nil { return nil, fmt.Errorf("charm is nil") } if exists, err := isNotDead(st.services, name); err != nil { return nil, err } else if exists { return nil, fmt.Errorf("service already exists") } env, err := st.Environment() if err != nil { return nil, err } else if env.Life() != Alive { return nil, fmt.Errorf("environment is no longer alive") } ownerId := tag.Id() if userExists, err := st.checkUserExists(ownerId); err != nil { return nil, err } else if !userExists { return nil, fmt.Errorf("user %v doesn't exist", ownerId) } // Create the service addition operations. peers := ch.Meta().Peers svcDoc := &serviceDoc{ Name: name, Series: ch.URL().Series, Subordinate: ch.Meta().Subordinate, CharmURL: ch.URL(), RelationCount: len(peers), Life: Alive, OwnerTag: ownerTag, } svc := newService(st, svcDoc) ops := []txn.Op{ env.assertAliveOp(), createConstraintsOp(st, svc.globalKey(), constraints.Value{}), // TODO(dimitern) 2014-04-04 bug #1302498 // Once we can add networks independently of machine // provisioning, we should check the given networks are valid // and known before setting them. createRequestedNetworksOp(st, svc.globalKey(), networks), createSettingsOp(st, svc.settingsKey(), nil), { C: st.users.Name, Id: ownerId, Assert: txn.DocExists, }, { C: st.settingsrefs.Name, Id: svc.settingsKey(), Assert: txn.DocMissing, Insert: settingsRefsDoc{1}, }, { C: st.services.Name, Id: name, Assert: txn.DocMissing, Insert: svcDoc, }} // Collect peer relation addition operations. peerOps, err := st.addPeerRelationsOps(name, peers) if err != nil { return nil, err } ops = append(ops, peerOps...) if err := st.runTransaction(ops); err == txn.ErrAborted { err := env.Refresh() if (err == nil && env.Life() != Alive) || errors.IsNotFound(err) { return nil, fmt.Errorf("environment is no longer alive") } else if err != nil { return nil, err } if userExists, ueErr := st.checkUserExists(ownerId); ueErr != nil { return nil, ueErr } else if !userExists { return nil, fmt.Errorf("unknown user %q", ownerId) } return nil, fmt.Errorf("service already exists") } else if err != nil { return nil, err } // Refresh to pick the txn-revno. if err = svc.Refresh(); err != nil { return nil, err } return svc, nil }
// TODO(axw) define an error for "no answer" func (s *jujuNameServer) answer(q dns.Question) (dns.RR, error) { if q.Qtype != dns.TypeA { return nil, nil } var envName string entityName := strings.ToLower(strings.TrimSuffix(q.Name, "."+zone)) if i := strings.IndexRune(entityName, '.'); i >= 0 { envName = entityName[i+1:] entityName = entityName[:i] } else { var err error envName, err = envcmd.GetDefaultEnvironment() if err != nil { return nil, err } } // TODO(axw) cache API connection api, err := s.openAPI(envName) if err != nil { return nil, err } defer api.Close() client := api.Client() // If the entity name parses as a tag, extract the ID. This enables // us to address "unit-mysql-0", where we couldn't otherwise, since // slashes are not allowed in domain names. Similarly for container // machines (e.g. to address "0/lxc/0", pass "machine-0-lxc-0"). if tag, err := names.ParseTag(entityName); err == nil { entityName = tag.Id() } var addr string if names.IsValidService(entityName) { status, err := client.Status([]string{entityName}) if err != nil { return nil, err } service := status.Services[entityName] addresses := make([]string, 0, len(service.Units)) for _, unit := range service.Units { if unit.PublicAddress == "" { continue } if includeLost || unit.UnitAgent.Status != "lost" { addresses = append(addresses, unit.PublicAddress) } } // Might be nice to have additional info in TXT? if len(addresses) == 0 { return nil, nil } addr = addresses[rand.Intn(len(addresses))] } else { // Assume it's a machine or unit name. addr, err = client.PublicAddress(entityName) if err != nil { return nil, err } } ip := net.ParseIP(addr) if ip != nil { rr := new(dns.A) rr.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0, } rr.A = ip return rr, nil } else { rr := new(dns.CNAME) rr.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 0, } rr.Target = addr + "." return rr, nil } }