// Common validations func (p *ProjectOptions) Validate() error { errList := []error{} if p.CheckSelector { if len(p.Selector) > 0 { if _, err := labels.Parse(p.Selector); err != nil { errList = append(errList, errors.New("--selector=<project_selector> must be a valid label selector")) } } if len(p.ProjectNames) != 0 { errList = append(errList, errors.New("either specify --selector=<project_selector> or projects but not both")) } } else if len(p.ProjectNames) == 0 { errList = append(errList, errors.New("must provide --selector=<project_selector> or projects")) } clusterNetwork, err := p.Oclient.ClusterNetwork().Get(sdnapi.ClusterNetworkDefault) if err != nil { if kapierrors.IsNotFound(err) { errList = append(errList, errors.New("Managing pod network is only supported for openshift multitenant network plugin")) } else { errList = append(errList, errors.New("Failed to fetch current network plugin info")) } } else if !sdnapi.IsOpenShiftMultitenantNetworkPlugin(clusterNetwork.PluginName) { errList = append(errList, fmt.Errorf("Using plugin: %q, managing pod network is only supported for openshift multitenant network plugin", clusterNetwork.PluginName)) } return kerrors.NewAggregate(errList) }
// Check is part of the Diagnostic interface; it runs the actual diagnostic logic func (d CheckServiceNetwork) Check() types.DiagnosticResult { d.res = types.NewDiagnosticResult(CheckServiceNetworkName) pluginName, ok, err := util.GetOpenShiftNetworkPlugin(d.OSClient) if err != nil { d.res.Error("DSvcNet1001", err, fmt.Sprintf("Checking network plugin failed. Error: %s", err)) return d.res } if !ok { d.res.Warn("DSvcNet1002", nil, "Skipping service connectivity test. Reason: Not using openshift network plugin.") return d.res } services, err := getAllServices(d.KubeClient) if err != nil { d.res.Error("DSvcNet1003", err, fmt.Sprintf("Getting all services failed. Error: %s", err)) return d.res } if len(services) == 0 { d.res.Warn("DSvcNet1004", nil, "Skipping service connectivity test. Reason: No services found.") return d.res } localPods, _, err := util.GetLocalAndNonLocalDiagnosticPods(d.KubeClient) if err != nil { d.res.Error("DSvcNet1005", err, fmt.Sprintf("Getting local and nonlocal pods failed. Error: %s", err)) return d.res } if sdnapi.IsOpenShiftMultitenantNetworkPlugin(pluginName) { netnsList, err := d.OSClient.NetNamespaces().List(kapi.ListOptions{}) if err != nil { d.res.Error("DSvcNet1006", err, fmt.Sprintf("Getting all network namespaces failed. Error: %s", err)) return d.res } d.vnidMap = map[string]uint32{} for _, netns := range netnsList.Items { d.vnidMap[netns.NetName] = netns.NetID } } localGlobalPods, localNonGlobalPods := util.GetGlobalAndNonGlobalPods(localPods, d.vnidMap) // Applicable to flat and multitenant networks if len(localGlobalPods) > 0 { d.checkConnection(localGlobalPods, services, "Skipping service connectivity test for global projects. Reason: Couldn't find a global pod.") } // Applicable to multitenant network isMultitenant := (d.vnidMap != nil) if isMultitenant { d.checkConnection(localNonGlobalPods, services, "Skipping service connectivity test for non-global projects. Reason: Couldn't find a non-global pod.") } return d.res }
// Called by higher layers to create the plugin SDN node instance func NewNodePlugin(pluginName string, osClient *osclient.Client, kClient *kclient.Client, hostname string, selfIP string, iptablesSyncPeriod time.Duration, mtu uint32) (*OsdnNode, error) { if !osapi.IsOpenShiftNetworkPlugin(pluginName) { return nil, nil } log.Infof("Initializing SDN node of type %q with configured hostname %q (IP %q), iptables sync period %q", pluginName, hostname, selfIP, iptablesSyncPeriod.String()) if hostname == "" { output, err := kexec.New().Command("uname", "-n").CombinedOutput() if err != nil { return nil, err } hostname = strings.TrimSpace(string(output)) log.Infof("Resolved hostname to %q", hostname) } if selfIP == "" { var err error selfIP, err = netutils.GetNodeIP(hostname) if err != nil { log.V(5).Infof("Failed to determine node address from hostname %s; using default interface (%v)", hostname, err) var defaultIP net.IP defaultIP, err = kubeutilnet.ChooseHostInterface() if err != nil { return nil, err } selfIP = defaultIP.String() log.Infof("Resolved IP address to %q", selfIP) } } ovsif, err := ovs.New(kexec.New(), BR) if err != nil { return nil, err } plugin := &OsdnNode{ multitenant: osapi.IsOpenShiftMultitenantNetworkPlugin(pluginName), kClient: kClient, osClient: osClient, ovs: ovsif, localIP: selfIP, hostName: hostname, vnids: newNodeVNIDMap(), podNetworkReady: make(chan struct{}), kubeletInitReady: make(chan struct{}), iptablesSyncPeriod: iptablesSyncPeriod, mtu: mtu, egressPolicies: make(map[uint32][]*osapi.EgressNetworkPolicy), } if err := plugin.dockerPreCNICleanup(); err != nil { return nil, err } return plugin, nil }
// Called by higher layers to create the proxy plugin instance; only used by nodes func NewProxyPlugin(pluginName string, osClient *osclient.Client, kClient *kclientset.Clientset) (*OsdnProxy, error) { if !osapi.IsOpenShiftMultitenantNetworkPlugin(pluginName) { return nil, nil } return &OsdnProxy{ kClient: kClient, osClient: osClient, firewall: make(map[string][]proxyFirewallItem), }, nil }
func (d *NetworkDiagnostic) TestSetup() error { d.nsName1 = kapi.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", util.NetworkDiagNamespacePrefix)) d.nsName2 = kapi.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", util.NetworkDiagNamespacePrefix)) nsList := []string{d.nsName1, d.nsName2} if sdnapi.IsOpenShiftMultitenantNetworkPlugin(d.pluginName) { d.globalnsName1 = kapi.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", util.NetworkDiagGlobalNamespacePrefix)) nsList = append(nsList, d.globalnsName1) d.globalnsName2 = kapi.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", util.NetworkDiagGlobalNamespacePrefix)) nsList = append(nsList, d.globalnsName2) } for _, name := range nsList { // Create a new namespace for network diagnostics ns := &kapi.Namespace{ObjectMeta: kapi.ObjectMeta{Name: name}} if _, err := d.KubeClient.Namespaces().Create(ns); err != nil { return fmt.Errorf("Creating namespace %q failed: %v", name, err) } if strings.HasPrefix(name, util.NetworkDiagGlobalNamespacePrefix) { if err := d.makeNamespaceGlobal(name); err != nil { return fmt.Errorf("Making namespace %q global failed: %v", name, err) } } } // Store kubeconfig as secret, used by network diagnostic pod kconfigData, err := d.getKubeConfig() if err != nil { return fmt.Errorf("Fetching kube config for network pod failed: %v", err) } secret := &kapi.Secret{} secret.Name = util.NetworkDiagSecretName secret.Data = map[string][]byte{strings.ToLower(kclientcmd.RecommendedConfigPathEnvVar): kconfigData} if _, err = d.KubeClient.Secrets(d.nsName1).Create(secret); err != nil { return fmt.Errorf("Creating secret %q failed: %v", secret.Name, err) } // Create test pods and services on all valid nodes if err := d.createTestPodAndService(nsList); err != nil { // Failed to create test pods/services on some nodes d.res.Error("DNet3001", err, fmt.Sprintf("Failed to create network diags test pod and service: %v", err)) } // Wait for test pods and services to be up and running on all valid nodes if err = d.waitForTestPodAndService(nsList); err != nil { return fmt.Errorf("Failed to run network diags test pod and service: %v", err) } return nil }
// Check is part of the Diagnostic interface; it runs the actual diagnostic logic func (d CheckPodNetwork) Check() types.DiagnosticResult { d.res = types.NewDiagnosticResult(CheckPodNetworkName) pluginName, ok, err := util.GetOpenShiftNetworkPlugin(d.OSClient) if err != nil { d.res.Error("DPodNet1001", err, fmt.Sprintf("Checking network plugin failed. Error: %s", err)) return d.res } if !ok { d.res.Warn("DPodNet1002", nil, "Skipping pod connectivity test. Reason: Not using openshift network plugin.") return d.res } localPods, nonlocalPods, err := util.GetLocalAndNonLocalDiagnosticPods(d.KubeClient) if err != nil { d.res.Error("DPodNet1003", err, fmt.Sprintf("Getting local and nonlocal pods failed. Error: %s", err)) return d.res } if sdnapi.IsOpenShiftMultitenantNetworkPlugin(pluginName) { netnsList, err := d.OSClient.NetNamespaces().List(kapi.ListOptions{}) if err != nil { d.res.Error("DPodNet1004", err, fmt.Sprintf("Getting all network namespaces failed. Error: %s", err)) return d.res } d.vnidMap = map[string]uint32{} for _, netns := range netnsList.Items { d.vnidMap[netns.NetName] = netns.NetID } } localGlobalPods, localNonGlobalPods := util.GetGlobalAndNonGlobalPods(localPods, d.vnidMap) nonlocalGlobalPods, nonlocalNonGlobalPods := util.GetGlobalAndNonGlobalPods(nonlocalPods, d.vnidMap) d.checkSameNodePodToPodConnection(localGlobalPods, localNonGlobalPods) d.checkDifferentNodePodToPodConnection(localGlobalPods, localNonGlobalPods, nonlocalGlobalPods, nonlocalNonGlobalPods) return d.res }
func StartMaster(networkConfig osconfigapi.MasterNetworkConfig, osClient *osclient.Client, kClient *kclientset.Clientset) error { if !osapi.IsOpenShiftNetworkPlugin(networkConfig.NetworkPluginName) { return nil } log.Infof("Initializing SDN master of type %q", networkConfig.NetworkPluginName) master := &OsdnMaster{ kClient: kClient, osClient: osClient, } var err error master.networkInfo, err = parseNetworkInfo(networkConfig.ClusterNetworkCIDR, networkConfig.ServiceNetworkCIDR) if err != nil { return err } createConfig := false updateConfig := false cn, err := master.osClient.ClusterNetwork().Get(osapi.ClusterNetworkDefault) if err == nil { if master.networkInfo.ClusterNetwork.String() != cn.Network || networkConfig.HostSubnetLength != cn.HostSubnetLength || master.networkInfo.ServiceNetwork.String() != cn.ServiceNetwork || networkConfig.NetworkPluginName != cn.PluginName { updateConfig = true } } else { cn = &osapi.ClusterNetwork{ TypeMeta: kapiunversioned.TypeMeta{Kind: "ClusterNetwork"}, ObjectMeta: kapi.ObjectMeta{Name: osapi.ClusterNetworkDefault}, } createConfig = true } if createConfig || updateConfig { if err = master.validateNetworkConfig(); err != nil { return err } size, len := master.networkInfo.ClusterNetwork.Mask.Size() if networkConfig.HostSubnetLength < 1 || networkConfig.HostSubnetLength >= uint32(len-size) { return fmt.Errorf("invalid HostSubnetLength %d for network %s (must be from 1 to %d)", networkConfig.HostSubnetLength, networkConfig.ClusterNetworkCIDR, len-size) } cn.Network = master.networkInfo.ClusterNetwork.String() cn.HostSubnetLength = networkConfig.HostSubnetLength cn.ServiceNetwork = master.networkInfo.ServiceNetwork.String() cn.PluginName = networkConfig.NetworkPluginName } if createConfig { cn, err := master.osClient.ClusterNetwork().Create(cn) if err != nil { return err } log.Infof("Created ClusterNetwork %s", clusterNetworkToString(cn)) } else if updateConfig { cn, err := master.osClient.ClusterNetwork().Update(cn) if err != nil { return err } log.Infof("Updated ClusterNetwork %s", clusterNetworkToString(cn)) } if err = master.SubnetStartMaster(master.networkInfo.ClusterNetwork, networkConfig.HostSubnetLength); err != nil { return err } if osapi.IsOpenShiftMultitenantNetworkPlugin(networkConfig.NetworkPluginName) { master.vnids = newMasterVNIDMap() if err = master.VnidStartMaster(); err != nil { return err } } return nil }