// AddEndpoints adds the specified endpoints to the remote application.
// If an endpoint with the same name already exists, an error is returned.
// If the endpoints change during the update, the operation is retried.
488929
func (s *RemoteApplication) AddEndpoints(eps []charm.Relation) error {
	newEps := make([]remoteEndpointDoc, len(eps))
	for i, ep := range eps {
		newEps[i] = remoteEndpointDoc{
			Name:      ep.Name,
			Role:      ep.Role,
			Interface: ep.Interface,
			Limit:     ep.Limit,
			Scope:     ep.Scope,
		}
	}

	model, err := s.st.Model()
	if err != nil {
		return errors.Trace(err)
	} else if model.Life() != Alive {
		return errors.Errorf("model is no longer alive")
	}

	checkCompatibleEndpoints := func(currentEndpoints []Endpoint) error {
		// Ensure there are no current endpoints with the same name as
		// any of those we want to update.
		currentEndpointNames := set.NewStrings()
		for _, ep := range currentEndpoints {
			currentEndpointNames.Add(ep.Name)
		}
		for _, r := range eps {
			if currentEndpointNames.Contains(r.Name) {
				return errors.AlreadyExistsf("endpoint %v", r.Name)
			}
		}
		return nil
	}

	currentEndpoints, err := s.Endpoints()
	if err != nil {
		return errors.Trace(err)
	}
	if err := checkCompatibleEndpoints(currentEndpoints); err != nil {
		return err
	}
	applicationID := s.st.docID(s.Name())
	buildTxn := func(attempt int) ([]txn.Op, error) {
		// If we've tried once already and failed, check that
		// model may have been destroyed.
		if attempt > 0 {
			if err := checkModelActive(s.st); err != nil {
				return nil, errors.Trace(err)
			}
			if err = s.Refresh(); err != nil {
				return nil, errors.Trace(err)
			}
			currentEndpoints, err = s.Endpoints()
			if err != nil {
				return nil, errors.Trace(err)
			}
			if err := checkCompatibleEndpoints(currentEndpoints); err != nil {
				return nil, err
			}
		}
		ops := []txn.Op{
			model.assertActiveOp(),
			{
				C:  remoteApplicationsC,
				Id: applicationID,
				Assert: bson.D{
					{"endpoints", bson.D{{
						"$not", bson.D{{
							"$elemMatch", bson.D{{
								"$in", newEps}},
						}},
					}}},
				},
				Update: bson.D{
					{"$addToSet", bson.D{{"endpoints", bson.D{{"$each", newEps}}}}},
				},
			},
		}
		return ops, nil
	}
	if err := s.st.db().Run(buildTxn); err != nil {
		return errors.Trace(err)
	}
	return s.Refresh()
}
330568
func (p *PodContainer) AddEndpoint(endpoint *PodEndpoint) *PodContainer {
	p.Endpoints = append(p.Endpoints, endpoint)
	return p
}
373007
func (a *api) GetEndpoints(serviceID string, reportImports, reportExports, validate bool) ([]applicationendpoint.EndpointReport, error) {
	client, err := a.connectMaster()
	if err != nil {
		return nil, err
	}

	serviceIDs := make([]string, 0)
	serviceIDs = append(serviceIDs, serviceID)
	if endpoints, err := client.GetServiceEndpoints(serviceIDs, reportImports, reportExports, validate); err != nil {
		return nil, err
	} else {
		return endpoints, nil
	}
}
656595
func (c *client) clusterEndpoints(ctx context.Context, dbname string) (clusterEndpointsResponse, error) {
	var url string
	if dbname == "" {
		url = "_api/cluster/endpoints"
	} else {
		url = path.Join("_db", pathEscape(dbname), "_api/cluster/endpoints")
	}
	req, err := c.conn.NewRequest("GET", url)
	if err != nil {
		return clusterEndpointsResponse{}, WithStack(err)
	}
	applyContextSettings(ctx, req)
	resp, err := c.conn.Do(ctx, req)
	if err != nil {
		return clusterEndpointsResponse{}, WithStack(err)
	}
	if err := resp.CheckStatus(200); err != nil {
		return clusterEndpointsResponse{}, WithStack(err)
	}
	var data clusterEndpointsResponse
	if err := resp.ParseBody("", &data); err != nil {
		return clusterEndpointsResponse{}, WithStack(err)
	}
	return data, nil
}
921300
func (s *Node) SetEndpoint(v *Endpoint) *Node {
	s.Endpoint = v
	return s
}
19337
func MakeServerEndpoints(s Service) Endpoints {
	return Endpoints{
		PostProfileEndpoint:   MakePostProfileEndpoint(s),
		GetProfileEndpoint:    MakeGetProfileEndpoint(s),
		PutProfileEndpoint:    MakePutProfileEndpoint(s),
		PatchProfileEndpoint:  MakePatchProfileEndpoint(s),
		DeleteProfileEndpoint: MakeDeleteProfileEndpoint(s),
		GetAddressesEndpoint:  MakeGetAddressesEndpoint(s),
		GetAddressEndpoint:    MakeGetAddressEndpoint(s),
		PostAddressEndpoint:   MakePostAddressEndpoint(s),
		DeleteAddressEndpoint: MakeDeleteAddressEndpoint(s),
	}
}
434645
func (s *SourceRegion) SetEndpoint(v string) *SourceRegion {
	s.Endpoint = &v
	return s
}
210473
func (s *ServiceCache) UpdateEndpoints(k8sEndpoints *types.Endpoints) (ServiceID, *Endpoints) {
	svcID, newEndpoints := ParseEndpoints(k8sEndpoints)

	s.mutex.Lock()
	defer s.mutex.Unlock()

	if oldEndpoints, ok := s.endpoints[svcID]; ok {
		if oldEndpoints.DeepEquals(newEndpoints) {
			return svcID, newEndpoints
		}
	}

	s.endpoints[svcID] = newEndpoints

	// Check if the corresponding Endpoints resource is already available
	service, ok := s.services[svcID]
	endpoints, serviceReady := s.correlateEndpoints(svcID)
	if ok && serviceReady {
		s.Events <- ServiceEvent{
			Action:    UpdateService,
			ID:        svcID,
			Service:   service,
			Endpoints: endpoints,
		}
	}

	return svcID, newEndpoints
}
900609
func CreateEndpoints(serverAddr string, args ...[]string) (string, EndpointList, SetupType, error) {
	var endpoints EndpointList
	var setupType SetupType
	var err error

	// Check whether serverAddr is valid for this host.
	if err = CheckLocalServerAddr(serverAddr); err != nil {
		return serverAddr, endpoints, setupType, err
	}

	_, serverAddrPort := mustSplitHostPort(serverAddr)

	// For single arg, return FS setup.
	if len(args) == 1 && len(args[0]) == 1 {
		var endpoint Endpoint
		endpoint, err = NewEndpoint(args[0][0])
		if err != nil {
			return serverAddr, endpoints, setupType, err
		}
		if err := endpoint.UpdateIsLocal(); err != nil {
			return serverAddr, endpoints, setupType, err
		}
		if endpoint.Type() != PathEndpointType {
			return serverAddr, endpoints, setupType, uiErrInvalidFSEndpoint(nil).Msg("use path style endpoint for FS setup")
		}
		endpoints = append(endpoints, endpoint)
		setupType = FSSetupType

		// Check for cross device mounts if any.
		if err = checkCrossDeviceMounts(endpoints); err != nil {
			return serverAddr, endpoints, setupType, uiErrInvalidFSEndpoint(nil).Msg(err.Error())
		}
		return serverAddr, endpoints, setupType, nil
	}

	for i, iargs := range args {
		var newEndpoints EndpointList
		// Convert args to endpoints
		var eps EndpointList
		eps, err = NewEndpointList(iargs...)
		if err != nil {
			return serverAddr, endpoints, setupType, uiErrInvalidErasureEndpoints(nil).Msg(err.Error())
		}

		// Check for cross device mounts if any.
		if err = checkCrossDeviceMounts(eps); err != nil {
			return serverAddr, endpoints, setupType, uiErrInvalidErasureEndpoints(nil).Msg(err.Error())
		}

		for _, ep := range eps {
			ep.SetIndex = i
			newEndpoints = append(newEndpoints, ep)
		}
		endpoints = append(endpoints, newEndpoints...)
	}

	// Return XL setup when all endpoints are path style.
	if endpoints[0].Type() == PathEndpointType {
		setupType = XLSetupType
		return serverAddr, endpoints, setupType, nil
	}

	if err := endpoints.UpdateIsLocal(); err != nil {
		return serverAddr, endpoints, setupType, uiErrInvalidErasureEndpoints(nil).Msg(err.Error())
	}

	// Here all endpoints are URL style.
	endpointPathSet := set.NewStringSet()
	localEndpointCount := 0
	localServerAddrSet := set.NewStringSet()
	localPortSet := set.NewStringSet()

	for _, endpoint := range endpoints {
		endpointPathSet.Add(endpoint.Path)
		if endpoint.IsLocal {
			localServerAddrSet.Add(endpoint.Host)

			var port string
			_, port, err = net.SplitHostPort(endpoint.Host)
			if err != nil {
				port = serverAddrPort
			}

			localPortSet.Add(port)

			localEndpointCount++
		}
	}

	// No local endpoint found.
	if localEndpointCount == 0 {
		return serverAddr, endpoints, setupType, uiErrInvalidErasureEndpoints(nil).Msg("no endpoint pointing to the local machine is found")
	}

	// Check whether same path is not used in endpoints of a host on different port.
	{
		pathIPMap := make(map[string]set.StringSet)
		for _, endpoint := range endpoints {
			var host string
			host, _, err = net.SplitHostPort(endpoint.Host)
			if err != nil {
				host = endpoint.Host
			}
			hostIPSet, _ := getHostIP(host)
			if IPSet, ok := pathIPMap[endpoint.Path]; ok {
				if !IPSet.Intersection(hostIPSet).IsEmpty() {
					return serverAddr, endpoints, setupType,
						uiErrInvalidErasureEndpoints(nil).Msg(fmt.Sprintf("path '%s' can not be served by different port on same address", endpoint.Path))
				}
				pathIPMap[endpoint.Path] = IPSet.Union(hostIPSet)
			} else {
				pathIPMap[endpoint.Path] = hostIPSet
			}
		}
	}

	// Check whether same path is used for more than 1 local endpoints.
	{
		localPathSet := set.CreateStringSet()
		for _, endpoint := range endpoints {
			if !endpoint.IsLocal {
				continue
			}
			if localPathSet.Contains(endpoint.Path) {
				return serverAddr, endpoints, setupType,
					uiErrInvalidErasureEndpoints(nil).Msg(fmt.Sprintf("path '%s' cannot be served by different address on same server", endpoint.Path))
			}
			localPathSet.Add(endpoint.Path)
		}
	}

	// Check whether serverAddrPort matches at least in one of port used in local endpoints.
	{
		if !localPortSet.Contains(serverAddrPort) {
			if len(localPortSet) > 1 {
				return serverAddr, endpoints, setupType,
					uiErrInvalidErasureEndpoints(nil).Msg("port number in server address must match with one of the port in local endpoints")
			}
			return serverAddr, endpoints, setupType,
				uiErrInvalidErasureEndpoints(nil).Msg("server address and local endpoint have different ports")
		}
	}

	// All endpoints are pointing to local host
	if len(endpoints) == localEndpointCount {
		// If all endpoints have same port number, then this is XL setup using URL style endpoints.
		if len(localPortSet) == 1 {
			if len(localServerAddrSet) > 1 {
				// TODO: Even though all endpoints are local, the local host is referred by different IP/name.
				// eg '172.0.0.1', 'localhost' and 'mylocalhostname' point to same local host.
				//
				// In this case, we bind to 0.0.0.0 ie to all interfaces.
				// The actual way to do is bind to only IPs in uniqueLocalHosts.
				serverAddr = net.JoinHostPort("", serverAddrPort)
			}

			endpointPaths := endpointPathSet.ToSlice()
			endpoints, _ = NewEndpointList(endpointPaths...)
			setupType = XLSetupType
			return serverAddr, endpoints, setupType, nil
		}

		// Even though all endpoints are local, but those endpoints use different ports.
		// This means it is DistXL setup.
	} else {
		// This is DistXL setup.
		// Check whether local server address are not 127.x.x.x
		for _, localServerAddr := range localServerAddrSet.ToSlice() {
			host, _, err := net.SplitHostPort(localServerAddr)
			if err != nil {
				host = localServerAddr
			}

			ipList, err := getHostIP(host)
			logger.FatalIf(err, "unexpected error when resolving host '%s'", host)

			// Filter ipList by IPs those start with '127.' or '::1'
			loopBackIPs := ipList.FuncMatch(func(ip string, matchString string) bool {
				return strings.HasPrefix(ip, "127.") || strings.HasPrefix(ip, "::1")
			}, "")

			// If loop back IP is found and ipList contains only loop back IPs, then error out.
			if len(loopBackIPs) > 0 && len(loopBackIPs) == len(ipList) {
				err = fmt.Errorf("'%s' resolves to loopback address is not allowed for distributed XL", localServerAddr)
				return serverAddr, endpoints, setupType, err
			}
		}
	}

	// Add missing port in all endpoints.
	for i := range endpoints {
		_, port, err := net.SplitHostPort(endpoints[i].Host)
		if err != nil {
			endpoints[i].Host = net.JoinHostPort(endpoints[i].Host, serverAddrPort)
		} else if endpoints[i].IsLocal && serverAddrPort != port {
			// If endpoint is local, but port is different than serverAddrPort, then make it as remote.
			endpoints[i].IsLocal = false
		}
	}

	uniqueArgs := set.NewStringSet()
	for _, endpoint := range endpoints {
		uniqueArgs.Add(endpoint.Host)
	}

	// Error out if we have more than serverCommandLineArgsMax unique servers.
	if len(uniqueArgs.ToSlice()) > serverCommandLineArgsMax {
		err := fmt.Errorf("Unsupported number of endpoints (%s), total number of servers cannot be more than %d", endpoints, serverCommandLineArgsMax)
		return serverAddr, endpoints, setupType, err
	}

	// Error out if we have less than 2 unique servers.
	if len(uniqueArgs.ToSlice()) < 2 && setupType == DistXLSetupType {
		err := fmt.Errorf("Unsupported number of endpoints (%s), minimum number of servers cannot be less than 2 in distributed setup", endpoints)
		return serverAddr, endpoints, setupType, err
	}

	_, dok := os.LookupEnv("MINIO_DOMAIN")
	_, eok := os.LookupEnv("MINIO_ETCD_ENDPOINTS")
	_, iok := os.LookupEnv("MINIO_PUBLIC_IPS")
	if dok && eok && !iok {
		updateDomainIPs(uniqueArgs)
	}

	setupType = DistXLSetupType
	return serverAddr, endpoints, setupType, nil
}
1061575
func (a *Application) defaultEndpointBindings() (map[string]string, error) {
	if a.doc.CharmURL == nil {
		return map[string]string{}, nil
	}

	appCharm, _, err := a.Charm()
	if err != nil {
		return nil, errors.Trace(err)
	}

	return DefaultEndpointBindingsForCharm(appCharm.Meta()), nil
}
267235
func LoadEndpoints(filename string, section string) Endpoints {
	config, err := ini.Load(filename)

	appManagerURL := "https://application.api.kumoru.io"
	if os.Getenv("APPLICATION_MANAGER_URL") != "" {
		appManagerURL = os.Getenv("APPLICATION_MANAGER_URL")
	}

	authManagerURL := "https://authorization.api.kumoru.io"
	if os.Getenv("AUTHORIZATION_MANAGER_URL") != "" {
		authManagerURL = os.Getenv("AUTHORIZATION_MANAGER_URL")
	}

	locationManagerURL := "https://location.api.kumoru.io"
	if os.Getenv("LOCATION_MANAGER_URL") != "" {
		locationManagerURL = os.Getenv("LOCATION_MANAGER_URL")
	}

	if err != nil {
		return Endpoints{
			Application:   appManagerURL,
			Authorization: authManagerURL,
			Location:      locationManagerURL,
		}
	}

	iniEndpoints, err := config.GetSection(section)
	if err != nil {
		return Endpoints{
			Application:   appManagerURL,
			Authorization: authManagerURL,
			Location:      locationManagerURL,
		}
	}

	return Endpoints{
		Application:   iniEndpoints.Key("kumoru_application_api").String(),
		Authorization: iniEndpoints.Key("kumoru_authorization_api").String(),
		Location:      iniEndpoints.Key("kumoru_location_api").String(),
	}
}
903441
func newEndpoints(c *CoreV1Client, namespace string) *endpoints {
	return &endpoints{
		client: c.RESTClient(),
		ns:     namespace,
	}
}
689099
func (a *Application) Endpoint(relationName string) (Endpoint, error) {
	eps, err := a.Endpoints()
	if err != nil {
		return Endpoint{}, err
	}
	for _, ep := range eps {
		if ep.Name == relationName {
			return ep, nil
		}
	}
	return Endpoint{}, errors.Errorf("application %q has no %q relation", a, relationName)
}
366493
func (s *HttpDataSourceConfig) SetEndpoint(v string) *HttpDataSourceConfig {
	s.Endpoint = &v
	return s
}
106658
func (c Client) Endpoint() endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (interface{}, error) {
		ctx, cancel := context.WithCancel(ctx)
		defer cancel()

		var (
			resp *http.Response
			err  error
		)
		if c.finalizer != nil {
			defer func() {
				if resp != nil {
					ctx = context.WithValue(ctx, httptransport.ContextKeyResponseHeaders, resp.Header)
					ctx = context.WithValue(ctx, httptransport.ContextKeyResponseSize, resp.ContentLength)
				}
				c.finalizer(ctx, err)
			}()
		}

		var params json.RawMessage
		if params, err = c.enc(ctx, request); err != nil {
			return nil, err
		}
		rpcReq := clientRequest{
			JSONRPC: "",
			Method:  c.method,
			Params:  params,
			ID:      c.requestID.Generate(),
		}

		req, err := http.NewRequest("POST", c.tgt.String(), nil)
		if err != nil {
			return nil, err
		}

		req.Header.Set("Content-Type", "application/json; charset=utf-8")
		var b bytes.Buffer
		req.Body = ioutil.NopCloser(&b)
		err = json.NewEncoder(&b).Encode(rpcReq)
		if err != nil {
			return nil, err
		}

		for _, f := range c.before {
			ctx = f(ctx, req)
		}

		resp, err = c.client.Do(req.WithContext(ctx))
		if err != nil {
			return nil, err
		}

		if !c.bufferedStream {
			defer resp.Body.Close()
		}

		// Decode the body into an object
		var rpcRes Response
		err = json.NewDecoder(resp.Body).Decode(&rpcRes)
		if err != nil {
			return nil, err
		}

		for _, f := range c.after {
			ctx = f(ctx, resp)
		}

		return c.dec(ctx, rpcRes)
	}
}
92722
func (s *DBClusterEndpoint) SetEndpoint(v string) *DBClusterEndpoint {
	s.Endpoint = &v
	return s
}
1246467
func (a *Application) EndpointBindings() (map[string]string, error) {
	// We don't need the TxnRevno below.
	bindings, _, err := readEndpointBindings(a.st, a.globalKey())
	if err != nil && !errors.IsNotFound(err) {
		return nil, errors.Trace(err)
	}
	if bindings == nil {
		bindings, err = a.defaultEndpointBindings()
		if err != nil {
			return nil, errors.Trace(err)
		}
	}
	return bindings, nil
}