예제 #1
0
// Validate makes sure that any labels specifed in Storage or Interfaces
// are unique, and that the required specifications are valid.
func (a *AllocateMachineArgs) Validate() error {
	storageLabels := set.NewStrings()
	for _, spec := range a.Storage {
		if err := spec.Validate(); err != nil {
			return errors.Annotate(err, "Storage")
		}
		if spec.Label != "" {
			if storageLabels.Contains(spec.Label) {
				return errors.NotValidf("reusing storage label %q", spec.Label)
			}
			storageLabels.Add(spec.Label)
		}
	}
	interfaceLabels := set.NewStrings()
	for _, spec := range a.Interfaces {
		if err := spec.Validate(); err != nil {
			return errors.Annotate(err, "Interfaces")
		}
		if interfaceLabels.Contains(spec.Label) {
			return errors.NotValidf("reusing interface label %q", spec.Label)
		}
		interfaceLabels.Add(spec.Label)
	}
	for _, v := range a.NotSpace {
		if v == "" {
			return errors.NotValidf("empty NotSpace constraint")
		}
	}
	return nil
}
예제 #2
0
func (m *Machine) validateLinkLayerDeviceParent(args *LinkLayerDeviceArgs) error {
	hostMachineID, parentDeviceName, err := parseLinkLayerDeviceParentNameAsGlobalKey(args.ParentName)
	if err != nil {
		return errors.Trace(err)
	} else if hostMachineID == "" {
		// Not a global key, so validate as usual.
		if err := m.validateParentDeviceNameWhenNotAGlobalKey(args); errors.IsNotFound(err) {
			return errors.NewNotValid(err, "ParentName not valid")
		} else if err != nil {
			return errors.Trace(err)
		}
		return nil
	}
	ourParentMachineID, hasParent := m.ParentId()
	if !hasParent {
		// Using global key for ParentName not allowed for non-container machine
		// devices.
		return errors.NotValidf("ParentName %q for non-container machine %q", args.ParentName, m.Id())
	}
	if hostMachineID != ourParentMachineID {
		// ParentName as global key only allowed when the key's machine ID is
		// the container's host machine.
		return errors.NotValidf("ParentName %q on non-host machine %q", args.ParentName, hostMachineID)
	}

	err = m.verifyHostMachineParentDeviceExistsAndIsABridgeDevice(hostMachineID, parentDeviceName)
	return errors.Trace(err)
}
예제 #3
0
func (m *Machine) validateSetDevicesAddressesArgs(args *LinkLayerDeviceAddress) error {
	if args.CIDRAddress == "" {
		return errors.NotValidf("empty CIDRAddress")
	}
	if _, _, err := net.ParseCIDR(args.CIDRAddress); err != nil {
		return errors.NewNotValid(err, "CIDRAddress")
	}

	if args.DeviceName == "" {
		return errors.NotValidf("empty DeviceName")
	}
	if !IsValidLinkLayerDeviceName(args.DeviceName) {
		logger.Warningf(
			"address %q on machine %q has invalid device name %q (using anyway)",
			args.CIDRAddress, m.Id(), args.DeviceName,
		)
	}
	if err := m.verifyDeviceAlreadyExists(args.DeviceName); err != nil {
		return errors.Trace(err)
	}

	if !IsValidAddressConfigMethod(string(args.ConfigMethod)) {
		return errors.NotValidf("ConfigMethod %q", args.ConfigMethod)
	}

	if args.GatewayAddress != "" {
		if ip := net.ParseIP(args.GatewayAddress); ip == nil {
			return errors.NotValidf("GatewayAddress %q", args.GatewayAddress)
		}
	}

	return nil
}
예제 #4
0
파일: image.go 프로젝트: bac/juju
func validateMetadata(m *imagesMetadataDoc) error {
	// series must be supplied.
	if m.Series == "" {
		return errors.NotValidf("missing series: metadata for image %v", m.ImageId)
	}
	v, err := series.SeriesVersion(m.Series)
	if err != nil {
		return err
	}
	m.Version = v

	if m.Stream == "" {
		return errors.NotValidf("missing stream: metadata for image %v", m.ImageId)
	}
	if m.Source == "" {
		return errors.NotValidf("missing source: metadata for image %v", m.ImageId)
	}
	if m.Arch == "" {
		return errors.NotValidf("missing architecture: metadata for image %v", m.ImageId)
	}
	if m.Region == "" {
		return errors.NotValidf("missing region: metadata for image %v", m.ImageId)
	}
	return nil
}
예제 #5
0
func parseAlterTable(scanner *bufio.Scanner) (*AlterTableQuery, error) {
	query := new(AlterTableQuery)
	scanner.Scan()
	query.Schema, query.Table = parseTableName(scanner.Text())
	scanner.Scan()
	query.Operation = AlterOp(strings.ToUpper(scanner.Text()))
	switch query.Operation {
	case ADD, MODIFY, DELETE:
	default:
		return nil, errors.NotValidf("Unrecognized ALTER operation '%v' in '%v'", query.Operation, scanner)
	}
	scanner.Scan()
	query.Column = stripQuotes(scanner.Text())
	if query.Column == "" {
		return nil, errors.NotValidf("Missing column name in '%v'", scanner)
	}
	scanner.Scan()
	query.Type = strings.ToUpper(scanner.Text())
	if query.Type == "" {
		return nil, errors.NotValidf("Missing column type in '%v'", scanner)
	}
	scanner.Scan()
	query.Extra = strings.ToUpper(scanner.Text())
	return query, nil
}
예제 #6
0
func (m *Machine) validateSetLinkLayerDeviceArgs(args *LinkLayerDeviceArgs) error {
	if args.Name == "" {
		return errors.NotValidf("empty Name")
	}
	if !IsValidLinkLayerDeviceName(args.Name) {
		logger.Warningf(
			"link-layer device %q on machine %q has invalid name (using anyway)",
			args.Name, m.Id(),
		)
	}

	if args.ParentName != "" {
		if err := m.validateLinkLayerDeviceParent(args); err != nil {
			return errors.Trace(err)
		}
	}

	if !IsValidLinkLayerDeviceType(string(args.Type)) {
		return errors.NotValidf("Type %q", args.Type)
	}

	if args.MACAddress != "" {
		if _, err := net.ParseMAC(args.MACAddress); err != nil {
			return errors.NotValidf("MACAddress %q", args.MACAddress)
		}
	}
	return nil
}
예제 #7
0
파일: audit.go 프로젝트: bac/juju
// Validate ensures that the entry considers itself to be in a
// complete and valid state.
func (e AuditEntry) Validate() error {
	if e.JujuServerVersion == version.Zero {
		return errors.NewNotValid(errors.NotAssignedf("JujuServerVersion"), "")
	}
	if e.ModelUUID == "" {
		return errors.NewNotValid(errors.NotAssignedf("ModelUUID"), "")
	}
	if utils.IsValidUUIDString(e.ModelUUID) == false {
		return errors.NotValidf("ModelUUID")
	}
	if e.Timestamp.IsZero() {
		return errors.NewNotValid(errors.NotAssignedf("Timestamp"), "")
	}
	if e.Timestamp.Location() != time.UTC {
		return errors.NewNotValid(errors.NotValidf("Timestamp"), "must be set to UTC")
	}
	if e.RemoteAddress == "" {
		return errors.NewNotValid(errors.NotAssignedf("RemoteAddress"), "")
	}
	if e.OriginType == "" {
		return errors.NewNotValid(errors.NotAssignedf("OriginType"), "")
	}
	if e.OriginName == "" {
		return errors.NewNotValid(errors.NotAssignedf("OriginName"), "")
	}
	if e.Operation == "" {
		return errors.NewNotValid(errors.NotAssignedf("Operation"), "")
	}

	// Data remains unchecked as it is always optional.

	return nil
}
예제 #8
0
파일: remote.go 프로젝트: bac/juju
// Validate checks the Remote fields for invalid values.
func (r Remote) Validate() error {
	if r.Name == "" {
		return errors.NotValidf("remote missing name,")
	}

	if r.isLocal() {
		if err := r.validateLocal(); err != nil {
			return errors.Trace(err)
		}
		return nil
	}

	if r.Protocol == "" {
		return errors.NotValidf("missing Protocol")
	}
	if r.Protocol != LXDProtocol && r.Protocol != SimplestreamsProtocol {
		return errors.NotValidf("unknown Protocol %q", r.Protocol)
	}

	// r.Cert is allowed to be nil for Public remotes
	if r.Cert != nil {
		if err := r.Cert.Validate(); err != nil {
			return errors.Trace(err)
		}
	}

	return nil
}
func (m *Machine) validateSetLinkLayerDeviceArgs(args *LinkLayerDeviceArgs) error {
	if args.Name == "" {
		return errors.NotValidf("empty Name")
	}
	if !IsValidLinkLayerDeviceName(args.Name) {
		return errors.NotValidf("Name %q", args.Name)
	}

	if args.ParentName != "" {
		if err := m.validateLinkLayerDeviceParent(args); err != nil {
			return errors.Trace(err)
		}
	}

	if !IsValidLinkLayerDeviceType(string(args.Type)) {
		return errors.NotValidf("Type %q", args.Type)
	}

	if args.MACAddress != "" {
		if _, err := net.ParseMAC(args.MACAddress); err != nil {
			return errors.NotValidf("MACAddress %q", args.MACAddress)
		}
	}
	return nil
}
예제 #10
0
파일: locallogin.go 프로젝트: bac/juju
func (h *localLoginHandlers) serveLoginPost(p httprequest.Params) (interface{}, error) {
	if err := p.Request.ParseForm(); err != nil {
		return nil, err
	}
	waitId := p.Request.Form.Get("waitid")
	if waitId == "" {
		return nil, errors.NotValidf("missing waitid")
	}
	username := p.Request.Form.Get("user")
	password := p.Request.Form.Get("password")
	if !names.IsValidUser(username) {
		return nil, errors.NotValidf("username %q", username)
	}
	userTag := names.NewUserTag(username)
	if !userTag.IsLocal() {
		return nil, errors.NotValidf("non-local username %q", username)
	}

	authenticator := h.authCtxt.authenticator(p.Request.Host)
	if _, err := authenticator.Authenticate(h.state, userTag, params.LoginRequest{
		Credentials: password,
	}); err != nil {
		// Mark the interaction as done (but failed),
		// unblocking a pending "/auth/wait" request.
		if err := h.authCtxt.localUserInteractions.Done(waitId, userTag, err); err != nil {
			if !errors.IsNotFound(err) {
				logger.Warningf(
					"failed to record completion of interaction %q for %q",
					waitId, userTag.Id(),
				)
			}
		}
		return nil, errors.Trace(err)
	}

	// Provide the client with a macaroon that they can use to
	// prove that they have logged in, and obtain a discharge
	// macaroon.
	m, err := h.authCtxt.CreateLocalLoginMacaroon(userTag)
	if err != nil {
		return nil, err
	}
	cookie, err := httpbakery.NewCookie(macaroon.Slice{m})
	if err != nil {
		return nil, err
	}
	http.SetCookie(p.Response, cookie)

	// Mark the interaction as done, unblocking a pending
	// "/auth/wait" request.
	if err := h.authCtxt.localUserInteractions.Done(
		waitId, userTag, nil,
	); err != nil {
		if errors.IsNotFound(err) {
			err = errors.New("login timed out")
		}
		return nil, err
	}
	return nil, nil
}
예제 #11
0
func (s CredentialSchema) processFileAttrValue(
	field NamedCredentialAttr, resultMap map[string]interface{}, newAttrs map[string]string,
	readFile func(string) ([]byte, error),
) error {
	name := field.Name
	if fieldVal, ok := resultMap[name]; ok {
		if _, ok := resultMap[field.FileAttr]; ok {
			return errors.NotValidf(
				"specifying both %q and %q",
				name, field.FileAttr,
			)
		}
		newAttrs[name] = fieldVal.(string)
		return nil
	}
	fieldVal, ok := resultMap[field.FileAttr]
	if !ok {
		return errors.NewNotValid(nil, fmt.Sprintf(
			"either %q or %q must be specified",
			name, field.FileAttr,
		))
	}
	data, err := readFile(fieldVal.(string))
	if err != nil {
		return errors.Annotatef(err, "reading file for %q", name)
	}
	if len(data) == 0 {
		return errors.NotValidf("empty file for %q", name)
	}
	newAttrs[name] = string(data)
	return nil
}
예제 #12
0
func (i *importer) unit(s description.Service, u description.Unit) error {
	i.logger.Debugf("importing unit %s", u.Name())

	// 1. construct a unitDoc
	udoc, err := i.makeUnitDoc(s, u)
	if err != nil {
		return errors.Trace(err)
	}

	// 2. construct a statusDoc for the workload status and agent status
	agentStatus := u.AgentStatus()
	if agentStatus == nil {
		return errors.NotValidf("missing agent status")
	}
	agentStatusDoc := i.makeStatusDoc(agentStatus)

	workloadStatus := u.WorkloadStatus()
	if workloadStatus == nil {
		return errors.NotValidf("missing workload status")
	}
	workloadStatusDoc := i.makeStatusDoc(workloadStatus)

	ops := addUnitOps(i.st, addUnitOpsArgs{
		unitDoc:           udoc,
		agentStatusDoc:    agentStatusDoc,
		workloadStatusDoc: workloadStatusDoc,
		meterStatusDoc: &meterStatusDoc{
			Code: u.MeterStatusCode(),
			Info: u.MeterStatusInfo(),
		},
	})
	// We should only have constraints for principal agents.
	// We don't encode that business logic here, if there are constraints
	// in the imported model, we put them in the database.
	if cons := u.Constraints(); cons != nil {
		agentGlobalKey := unitAgentGlobalKey(u.Name())
		ops = append(ops, createConstraintsOp(i.st, agentGlobalKey, i.constraints(cons)))
	}

	if err := i.st.runTransaction(ops); err != nil {
		return errors.Trace(err)
	}

	unit := newUnit(i.st, udoc)
	if annotations := u.Annotations(); len(annotations) > 0 {
		if err := i.st.SetAnnotations(unit, annotations); err != nil {
			return errors.Trace(err)
		}
	}
	if err := i.importStatusHistory(unit.globalKey(), u.WorkloadStatusHistory()); err != nil {
		return errors.Trace(err)
	}
	if err := i.importStatusHistory(unit.globalAgentKey(), u.AgentStatusHistory()); err != nil {
		return errors.Trace(err)
	}

	return nil
}
예제 #13
0
// Validate validates the Azure provider configuration.
func (cfg ProviderConfig) Validate() error {
	if cfg.NewStorageClient == nil {
		return errors.NotValidf("nil NewStorageClient")
	}
	if cfg.StorageAccountNameGenerator == nil {
		return errors.NotValidf("nil StorageAccountNameGenerator")
	}
	return nil
}
예제 #14
0
파일: dumb.go 프로젝트: bac/juju
// Validate returns an error if config cannot drive a DumbWorkers.
func (config DumbConfig) Validate() error {
	if config.Factory == nil {
		return errors.NotValidf("nil Factory")
	}
	if config.Logger == (loggo.Logger{}) {
		return errors.NotValidf("uninitialized Logger")
	}
	return nil
}
예제 #15
0
파일: worker.go 프로젝트: makyo/juju
// Validate returns an error if config cannot drive a Worker.
func (config Config) Validate() error {
	if config.Facade == nil {
		return errors.NotValidf("nil Facade")
	}
	if config.Guard == nil {
		return errors.NotValidf("nil Guard")
	}
	return nil
}
예제 #16
0
파일: environ.go 프로젝트: xushiwei/juju
// Validate returns an error if the config cannot be used to start a Tracker.
func (config Config) Validate() error {
	if config.Observer == nil {
		return errors.NotValidf("nil Observer")
	}
	if config.NewEnvironFunc == nil {
		return errors.NotValidf("nil NewEnvironFunc")
	}
	return nil
}
예제 #17
0
파일: cloudspec.go 프로젝트: bac/juju
// Validate validates that the CloudSpec is well-formed. It does
// not ensure that the cloud type and credentials are valid.
func (cs CloudSpec) Validate() error {
	if cs.Type == "" {
		return errors.NotValidf("empty Type")
	}
	if !names.IsValidCloud(cs.Name) {
		return errors.NotValidf("cloud name %q", cs.Name)
	}
	return nil
}
예제 #18
0
func (config Config) Validate() error {
	if config.Facade == nil {
		return errors.NotValidf("nil Facade")
	}
	if config.Environ == nil {
		return errors.NotValidf("nil Environ")
	}
	return nil
}
예제 #19
0
파일: worker.go 프로젝트: makyo/juju
// Validate returns an error if Config cannot drive a hostkeyreporter.
func (config Config) Validate() error {
	if config.Facade == nil {
		return errors.NotValidf("nil Facade")
	}
	if config.MachineId == "" {
		return errors.NotValidf("empty MachineId")
	}
	return nil
}
예제 #20
0
파일: machiner.go 프로젝트: bac/juju
// Validate reports whether or not the configuration is valid.
func (cfg *Config) Validate() error {
	if cfg.MachineAccessor == nil {
		return errors.NotValidf("unspecified MachineAccessor")
	}
	if cfg.Tag == (names.MachineTag{}) {
		return errors.NotValidf("unspecified Tag")
	}
	return nil
}
예제 #21
0
파일: runlistener.go 프로젝트: imoapps/juju
func (cfg *RunListenerConfig) Validate() error {
	if cfg.SocketPath == "" {
		return errors.NotValidf("SocketPath unspecified")
	}
	if cfg.CommandRunner == nil {
		return errors.NotValidf("CommandRunner unspecified")
	}
	return nil
}
예제 #22
0
func validateUser(name string) error {
	if !names.IsValidUser(name) {
		return errors.NotValidf("account name %q", name)
	}
	if tag := names.NewUserTag(name); tag.Id() != tag.Canonical() {
		return errors.NotValidf("unqualified account name %q", name)
	}
	return nil
}
예제 #23
0
// ValidateControllerDetails ensures that given controller details are valid.
func ValidateControllerDetails(details ControllerDetails) error {
	if details.ControllerUUID == "" {
		return errors.NotValidf("missing uuid, controller details")
	}
	if details.CACert == "" {
		return errors.NotValidf("missing ca-cert, controller details")
	}
	return nil
}
예제 #24
0
// ValidateBootstrapConfig validates the given boostrap config.
func ValidateBootstrapConfig(cfg BootstrapConfig) error {
	if cfg.Cloud == "" {
		return errors.NotValidf("empty cloud name")
	}
	if len(cfg.Config) == 0 {
		return errors.NotValidf("empty config")
	}
	return nil
}
예제 #25
0
파일: apiserver.go 프로젝트: kat-co/juju
func (c *ServerConfig) Validate() error {
	if c.Clock == nil {
		return errors.NotValidf("missing Clock")
	}
	if c.NewObserver == nil {
		return errors.NotValidf("missing NewObserver")
	}

	return nil
}
예제 #26
0
파일: remote.go 프로젝트: bac/juju
func (r Remote) validateLocal() error {
	if r.Cert != nil {
		return errors.NotValidf("hostless remote with cert")
	}
	if r.Protocol != LXDProtocol {
		return errors.NotValidf("localhost always talks LXD protocol not: %s", r.Protocol)
	}

	return nil
}
예제 #27
0
// Validate ensures that there is a positive size and that there are no Empty
// tag values.
func (s *StorageSpec) Validate() error {
	if s.Size <= 0 {
		return errors.NotValidf("Size value %d", s.Size)
	}
	for _, v := range s.Tags {
		if v == "" {
			return errors.NotValidf("empty tag")
		}
	}
	return nil
}
예제 #28
0
// Validate ensures that a Label is specified and that there is at least one
// Space or NotSpace value set.
func (a *InterfaceSpec) Validate() error {
	if a.Label == "" {
		return errors.NotValidf("missing Label")
	}
	// Perhaps at some stage in the future there will be other possible specs
	// supported (like vid, subnet, etc), but until then, just space to check.
	if a.Space == "" {
		return errors.NotValidf("empty Space constraint")
	}
	return nil
}
예제 #29
0
func (m *Manager) UpdateTopic(topic string, partitions int) error {

	if topic == groupMetadataTopicName {
		return errors.NotValidf("cannot modify internal topic")
	}

	topicPath := fmt.Sprintf("%s%s/%s", m.kafkaRoot, brokerTopics, topic)
	topicAssignData, _, err := m.zkClient.Get(topicPath)
	if err != nil {
		return errors.Trace(err)
	}

	partitionConfig := topicPatitionConfig{}
	err = json.Unmarshal(topicAssignData, &partitionConfig)
	if err != nil {
		return errors.Trace(err)
	}

	partitionsToAdd := partitions - len(partitionConfig.Partitions)
	if partitionsToAdd <= 0 {
		return errors.Errorf("partition can only be increased")
	}

	//partition start with "0"
	replicationList := partitionConfig.Partitions["0"]
	if len(replicationList) == 0 {
		return errors.Errorf("exist replication is 0")
	}

	m.mu.Lock()
	brokersList := m.brokersList
	m.mu.Unlock()

	newAssignment, err := assignReplicasToBrokers(brokersList, int32(partitionsToAdd),
		int32(len(replicationList)), replicationList[0], int32(len(partitionConfig.Partitions)))
	if err != nil {
		return errors.Trace(err)
	}

	// check if new assignment has the right replication factor
	for partition, assign := range newAssignment {
		if len(assign) != len(replicationList) {
			return errors.NotValidf("new replication assignment %v", newAssignment)
		}
		partitionConfig.Partitions[partition] = assign
	}

	err = m.createOrUpdateTopicPartitionAssignmentPathInZK(topic, partitionConfig.Partitions, true)
	if err != nil {
		return errors.Trace(err)
	}

	return nil
}
예제 #30
0
파일: config.go 프로젝트: imoapps/juju
// Validate returns an error if the configuration contains invalid information
// or missing resources.
func (config ManagerConfig) Validate() error {
	if config.Client == nil {
		return errors.NotValidf("nil Client")
	}
	if config.Clock == nil {
		return errors.NotValidf("nil Clock")
	}
	if config.MaxSleep <= 0 {
		return errors.NotValidf("non-positive MaxSleep")
	}
	return nil
}