// UpdateHost information for a registered host func (f *Facade) UpdateHost(ctx datastore.Context, entity *host.Host) error { glog.V(2).Infof("Facade.UpdateHost: %+v", entity) // validate the host exists if host, err := f.GetHost(ctx, entity.ID); err != nil { return err } else if host == nil { return fmt.Errorf("host does not exist: %s", entity.ID) } // validate the pool exists if pool, err := f.GetResourcePool(ctx, entity.PoolID); err != nil { return err } else if pool == nil { return fmt.Errorf("pool does not exist: %s", entity.PoolID) } var err error ec := newEventCtx() defer f.afterEvent(afterHostAdd, ec, entity, err) if err = f.beforeEvent(beforeHostAdd, ec, entity); err != nil { return err } entity.UpdatedAt = time.Now() if err = f.hostStore.Put(ctx, host.HostKey(entity.ID), entity); err != nil { return err } err = zkAPI(f).UpdateHost(entity) return err }
// AddHost register a host with serviced. Returns an error if host already // exists or if the host's IP is a virtual IP func (f *Facade) AddHost(ctx datastore.Context, entity *host.Host) error { glog.V(2).Infof("Facade.AddHost: %v", entity) exists, err := f.GetHost(ctx, entity.ID) if err != nil { return err } if exists != nil { return fmt.Errorf("host already exists: %s", entity.ID) } // only allow hostid of master if SERVICED_REGISTRY is false if !docker.UseRegistry() { masterHostID, err := utils.HostID() if err != nil { return fmt.Errorf("unable to retrieve hostid %s: %s", entity.ID, err) } if entity.ID != masterHostID { return fmt.Errorf("SERVICED_REGISTRY is false and hostid %s does not match master %s", entity.ID, masterHostID) } } // validate Pool exists pool, err := f.GetResourcePool(ctx, entity.PoolID) if err != nil { return fmt.Errorf("error verifying pool exists: %v", err) } if pool == nil { return fmt.Errorf("error creating host, pool %s does not exists", entity.PoolID) } // verify that there are no virtual IPs with the given host IP(s) for _, ip := range entity.IPs { if exists, err := f.HasIP(ctx, pool.ID, ip.IPAddress); err != nil { return fmt.Errorf("error verifying ip %s exists: %v", ip.IPAddress, err) } else if exists { return fmt.Errorf("pool already has a virtual ip %s", ip.IPAddress) } } ec := newEventCtx() err = nil defer f.afterEvent(afterHostAdd, ec, entity, err) if err = f.beforeEvent(beforeHostAdd, ec, entity); err != nil { return err } now := time.Now() entity.CreatedAt = now entity.UpdatedAt = now if err = f.hostStore.Put(ctx, host.HostKey(entity.ID), entity); err != nil { return err } err = zkAPI(f).AddHost(entity) return err }
// RemoveHost removes a Host from serviced func (f *Facade) RemoveHost(ctx datastore.Context, hostID string) (err error) { glog.V(2).Infof("Facade.RemoveHost: %s", hostID) //assert valid host var _host *host.Host if _host, err = f.GetHost(ctx, hostID); err != nil { return err } else if _host == nil { return fmt.Errorf("HostID %s does not exist", hostID) } ec := newEventCtx() defer f.afterEvent(afterHostDelete, ec, hostID, err) if err = f.beforeEvent(beforeHostDelete, ec, hostID); err != nil { return err } //remove host from zookeeper if err = zkAPI(f).RemoveHost(_host); err != nil { return err } //remove host from datastore if err = f.hostStore.Delete(ctx, host.HostKey(hostID)); err != nil { return err } //grab all services that are address assigned the host's IPs var services []service.Service for _, ip := range _host.IPs { query := []string{fmt.Sprintf("Endpoints.AddressAssignment.IPAddr:%s", ip.IPAddress)} svcs, err := f.GetTaggedServices(ctx, query) if err != nil { glog.Errorf("Failed to grab services with endpoints assigned to ip %s on host %s: %s", ip.IPAddress, _host.Name, err) return err } services = append(services, svcs...) } // update address assignments for _, svc := range services { request := dao.AssignmentRequest{ ServiceID: svc.ID, IPAddress: "", AutoAssignment: true, } if err = f.AssignIPs(ctx, request); err != nil { glog.Warningf("Failed assigning another ip to service %s: %s", svc.ID, err) } } return nil }
// GetHost gets a host by id. Returns nil if host not found func (f *Facade) GetHost(ctx datastore.Context, hostID string) (*host.Host, error) { glog.V(2).Infof("Facade.GetHost: id=%s", hostID) var value host.Host err := f.hostStore.Get(ctx, host.HostKey(hostID), &value) glog.V(4).Infof("Facade.GetHost: get error %v", err) if datastore.IsErrNoSuchEntity(err) { return nil, nil } if err != nil { return nil, err } return &value, nil }