// RunApiServer starts an API server in a go routine. func RunApiServer(cl *client.Client, etcdClient tools.EtcdClient, addr string, port int) { handler := delegateHandler{} helper, err := master.NewEtcdHelper(etcdClient, "") if err != nil { glog.Fatalf("Unable to get etcd helper: %v", err) } // Create a master and install handlers into mux. m := master.New(&master.Config{ Client: cl, EtcdHelper: helper, KubeletClient: &client.HTTPKubeletClient{ Client: http.DefaultClient, Port: 10250, }, EnableLogsSupport: false, APIPrefix: "/api", Authorizer: apiserver.NewAlwaysAllowAuthorizer(), ReadWritePort: port, ReadOnlyPort: port, PublicAddress: addr, }) mux := http.NewServeMux() apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(mux, "/api/v1beta1") apiserver.NewAPIGroup(m.API_v1beta2()).InstallREST(mux, "/api/v1beta2") apiserver.InstallSupport(mux) handler.delegate = mux go http.ListenAndServe(fmt.Sprintf("%s:%d", addr, port), &handler) }
func TestBuildConfigClient(t *testing.T) { etcdClient := newEtcdClient() m := master.New(&master.Config{ EtcdServers: etcdClient.GetCluster(), }) osMux := http.NewServeMux() storage := map[string]apiserver.RESTStorage{ "builds": buildregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "buildConfigs": buildconfigregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), } apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(osMux, "/api/v1beta1") apiserver.NewAPIGroup(storage, runtime.Codec).InstallREST(osMux, "/osapi/v1beta1") apiserver.InstallSupport(osMux) s := httptest.NewServer(osMux) kubeclient := client.NewOrDie(s.URL, nil) osclient, _ := osclient.New(s.URL, nil) info, err := kubeclient.ServerVersion() if err != nil { t.Fatalf("unexpected error: %v", err) } if e, a := version.Get(), *info; !reflect.DeepEqual(e, a) { t.Errorf("expected %#v, got %#v", e, a) } buildConfigs, err := osclient.ListBuildConfigs(labels.Everything()) if err != nil { t.Fatalf("unexpected error %v", err) } if len(buildConfigs.Items) != 0 { t.Errorf("expected no buildConfigs, got %#v", buildConfigs) } // get a validation error buildConfig := &api.BuildConfig{ Labels: map[string]string{ "label1": "value1", "label2": "value2", }, DesiredInput: api.BuildInput{ Type: api.DockerBuildType, SourceURI: "http://my.docker/build", ImageTag: "namespace/builtimage", BuilderImage: "anImage", }, } got, err := osclient.CreateBuildConfig(buildConfig) if err == nil { t.Fatalf("unexpected non-error: %v", err) } // get a created buildConfig buildConfig.DesiredInput.BuilderImage = "" got, err = osclient.CreateBuildConfig(buildConfig) if err != nil { t.Fatalf("unexpected error: %v", err) } if got.ID == "" { t.Errorf("unexpected empty buildConfig ID %v", got) } // get a list of buildConfigs buildConfigs, err = osclient.ListBuildConfigs(labels.Everything()) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(buildConfigs.Items) != 1 { t.Errorf("expected one buildConfig, got %#v", buildConfigs) } actual := buildConfigs.Items[0] if actual.ID != got.ID { t.Errorf("expected buildConfig %#v, got %#v", got, actual) } // delete a buildConfig err = osclient.DeleteBuildConfig(got.ID) if err != nil { t.Fatalf("unexpected error %v", err) } buildConfigs, err = osclient.ListBuildConfigs(labels.Everything()) if err != nil { t.Fatalf("unexpected error %v", err) } if len(buildConfigs.Items) != 0 { t.Errorf("expected no buildConfigs, got %#v", buildConfigs) } }
// init initializes master. func (m *Master) init(c *Config) { podCache := NewPodCache(c.KubeletClient, m.podRegistry) go util.Forever(func() { podCache.UpdateAllContainers() }, time.Second*30) var userContexts = handlers.NewUserRequestContext() var authenticator authenticator.Request if len(c.TokenAuthFile) != 0 { tokenAuthenticator, err := tokenfile.New(c.TokenAuthFile) if err != nil { glog.Fatalf("Unable to load the token authentication file '%s': %v", c.TokenAuthFile, err) } authenticator = bearertoken.New(tokenAuthenticator) } m.storage = map[string]apiserver.RESTStorage{ "pods": pod.NewREST(&pod.RESTConfig{ CloudProvider: c.Cloud, PodCache: podCache, PodInfoGetter: c.KubeletClient, Registry: m.podRegistry, Minions: m.client.Minions(), }), "replicationControllers": controller.NewREST(m.controllerRegistry, m.podRegistry), "services": service.NewREST(m.serviceRegistry, c.Cloud, m.minionRegistry, m.portalNet), "endpoints": endpoint.NewREST(m.endpointRegistry), "minions": minion.NewREST(m.minionRegistry), "events": event.NewREST(m.eventRegistry), // TODO: should appear only in scheduler API group. "bindings": binding.NewREST(m.bindingRegistry), } apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(m.mux, c.APIPrefix+"/v1beta1") apiserver.NewAPIGroup(m.API_v1beta2()).InstallREST(m.mux, c.APIPrefix+"/v1beta2") versionHandler := apiserver.APIVersionHandler("v1beta1", "v1beta2") m.mux.Handle(c.APIPrefix, versionHandler) apiserver.InstallSupport(m.mux) serversToValidate := m.getServersToValidate(c) apiserver.InstallValidator(m.mux, serversToValidate) if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.mux) } if c.EnableUISupport { ui.InstallSupport(m.mux) } handler := http.Handler(m.mux.(*http.ServeMux)) if len(c.CorsAllowedOriginList) > 0 { allowedOriginRegexps, err := util.CompileRegexps(c.CorsAllowedOriginList) if err != nil { glog.Fatalf("Invalid CORS allowed origin, --cors_allowed_origins flag was set to %v - %v", strings.Join(c.CorsAllowedOriginList, ","), err) } handler = apiserver.CORS(handler, allowedOriginRegexps, nil, nil, "true") } m.InsecureHandler = handler attributeGetter := apiserver.NewRequestAttributeGetter(userContexts) handler = apiserver.WithAuthorizationCheck(handler, attributeGetter, m.authorizer) // Install Authenticator if authenticator != nil { handler = handlers.NewRequestAuthenticator(userContexts, authenticator, handlers.Unauthorized, handler) } m.mux.HandleFunc("/_whoami", handleWhoAmI(authenticator)) m.Handler = handler // TODO: Attempt clean shutdown? m.masterServices.Start() }
func (c *config) startAllInOne() { minionHost := "127.0.0.1" minionPort := 10250 rootDirectory := path.Clean("/var/lib/openshift") osAddr := c.ListenAddr osPrefix := "/osapi/v1beta1" kubePrefix := "/api/v1beta1" kubeClient, err := kubeclient.New("http://"+osAddr, nil) if err != nil { glog.Fatalf("Unable to configure client - bad URL: %v", err) } osClient, err := osclient.New("http://"+osAddr, nil) if err != nil { glog.Fatalf("Unable to configure client - bad URL: %v", err) } etcdAddr := "127.0.0.1:4001" etcdServers := []string{} // default etcdConfig := etcdconfig.New() etcdConfig.BindAddr = etcdAddr etcdConfig.DataDir = "openshift.local.etcd" etcdConfig.Name = "openshift.local" // check docker connection dockerClient, dockerAddr := c.Docker.GetClientOrExit() if err := dockerClient.Ping(); err != nil { glog.Errorf("WARNING: Docker could not be reached at %s. Docker must be installed and running to start containers.\n%v", dockerAddr, err) } else { glog.Infof("Connecting to Docker at %s", dockerAddr) } cadvisorClient, err := cadvisor.NewClient("http://127.0.0.1:4194") if err != nil { glog.Errorf("Error on creating cadvisor client: %v", err) } // initialize etcd etcdServer := etcd.New(etcdConfig) go util.Forever(func() { glog.Infof("Started etcd at http://%s", etcdAddr) etcdServer.Run() }, 0) etcdClient := etcdclient.NewClient(etcdServers) for i := 0; ; i += 1 { _, err := etcdClient.Get("/", false, false) if err == nil || tools.IsEtcdNotFound(err) { break } if i > 100 { glog.Fatal("Could not reach etcd: %v", err) } time.Sleep(50 * time.Millisecond) } // initialize Kubelet os.MkdirAll(rootDirectory, 0750) cfg := kconfig.NewPodConfig(kconfig.PodConfigNotificationSnapshotAndUpdates) kconfig.NewSourceEtcd(kconfig.EtcdKeyForHost(minionHost), etcdClient, cfg.Channel("etcd")) k := kubelet.NewMainKubelet( minionHost, dockerClient, cadvisorClient, etcdClient, rootDirectory, 30*time.Second) go util.Forever(func() { k.Run(cfg.Updates()) }, 0) go util.Forever(func() { kubelet.ListenAndServeKubeletServer(k, cfg.Channel("http"), minionHost, uint(minionPort)) }, 0) imageRegistry := image.NewEtcdRegistry(etcdClient) // initialize OpenShift API storage := map[string]apiserver.RESTStorage{ "builds": buildregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "buildConfigs": buildconfigregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "images": image.NewImageStorage(imageRegistry), "imageRepositories": image.NewImageRepositoryStorage(imageRegistry), "imageRepositoryMappings": image.NewImageRepositoryMappingStorage(imageRegistry, imageRegistry), "templateConfigs": template.NewStorage(), } osMux := http.NewServeMux() // initialize Kubernetes API podInfoGetter := &kubeclient.HTTPPodInfoGetter{ Client: http.DefaultClient, Port: uint(minionPort), } masterConfig := &master.Config{ Client: kubeClient, EtcdServers: etcdServers, HealthCheckMinions: true, Minions: []string{minionHost}, PodInfoGetter: podInfoGetter, } m := master.New(masterConfig) apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(osMux, kubePrefix) apiserver.NewAPIGroup(storage, runtime.Codec).InstallREST(osMux, osPrefix) apiserver.InstallSupport(osMux) osApi := &http.Server{ Addr: osAddr, Handler: apiserver.RecoverPanics(osMux), ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, MaxHeaderBytes: 1 << 20, } go util.Forever(func() { glog.Infof("Started Kubernetes API at http://%s%s", osAddr, kubePrefix) glog.Infof("Started OpenShift API at http://%s%s", osAddr, osPrefix) glog.Fatal(osApi.ListenAndServe()) }, 0) // initialize kube proxy serviceConfig := pconfig.NewServiceConfig() endpointsConfig := pconfig.NewEndpointsConfig() pconfig.NewConfigSourceEtcd(etcdClient, serviceConfig.Channel("etcd"), endpointsConfig.Channel("etcd")) loadBalancer := proxy.NewLoadBalancerRR() proxier := proxy.NewProxier(loadBalancer) serviceConfig.RegisterHandler(proxier) endpointsConfig.RegisterHandler(loadBalancer) glog.Infof("Started Kubernetes Proxy") // initialize replication manager controllerManager := controller.NewReplicationManager(kubeClient) controllerManager.Run(10 * time.Second) glog.Infof("Started Kubernetes Replication Manager") // initialize scheduler configFactory := &factory.ConfigFactory{Client: kubeClient} config := configFactory.Create() s := scheduler.New(config) s.Run() glog.Infof("Started Kubernetes Scheduler") // initialize build controller dockerBuilderImage := env("OPENSHIFT_DOCKER_BUILDER_IMAGE", "openshift/docker-builder") useHostDockerSocket := len(env("USE_HOST_DOCKER_SOCKET", "")) > 0 stiBuilderImage := env("OPENSHIFT_STI_BUILDER_IMAGE", "openshift/sti-builder") dockerRegistry := env("DOCKER_REGISTRY", "") buildStrategies := map[buildapi.BuildType]build.BuildJobStrategy{ buildapi.DockerBuildType: strategy.NewDockerBuildStrategy(dockerBuilderImage, useHostDockerSocket), buildapi.STIBuildType: strategy.NewSTIBuildStrategy(stiBuilderImage, useHostDockerSocket), } buildController := build.NewBuildController(kubeClient, osClient, buildStrategies, dockerRegistry, 1200) buildController.Run(10 * time.Second) select {} }
func TestWebhookGithubPush(t *testing.T) { etcdClient := newEtcdClient() m := master.New(&master.Config{ EtcdServers: etcdClient.GetCluster(), }) osMux := http.NewServeMux() storage := map[string]apiserver.RESTStorage{ "builds": buildregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "buildConfigs": buildconfigregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), } apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(osMux, "/api/v1beta1") osPrefix := "/osapi/v1beta1" apiserver.NewAPIGroup(storage, runtime.Codec).InstallREST(osMux, osPrefix) apiserver.InstallSupport(osMux) s := httptest.NewServer(osMux) kubeclient := client.NewOrDie(s.URL, nil) osClient, _ := osclient.New(s.URL, nil) whPrefix := osPrefix + "/buildConfigHooks/" osMux.Handle(whPrefix, http.StripPrefix(whPrefix, webhook.NewController(osClient, map[string]webhook.Plugin{ "github": github.New(), }))) info, err := kubeclient.ServerVersion() if err != nil { t.Fatalf("Unexpected error: %v", err) } if e, a := version.Get(), *info; !reflect.DeepEqual(e, a) { t.Errorf("Expected %#v, got %#v", e, a) } // create buildconfig buildConfig := &buildapi.BuildConfig{ JSONBase: kubeapi.JSONBase{ ID: "build100", }, DesiredInput: buildapi.BuildInput{ Type: buildapi.DockerBuildType, SourceURI: "http://my.docker/build", ImageTag: "namespace/builtimage", }, Secret: "secret101", } if _, err := osClient.CreateBuildConfig(buildConfig); err != nil { t.Fatalf("Unexpected error: %v", err) } // trigger build event sending push notification client := &http.Client{} data, err := ioutil.ReadFile("../../pkg/build/webhook/github/fixtures/pushevent.json") if err != nil { t.Fatalf("Failed to open pushevent.json: %v", err) } req, err := http.NewRequest("POST", s.URL+whPrefix+"build100/secret101/github", bytes.NewReader(data)) if err != nil { t.Fatalf("Error creating POST request: %v", err) } req.Header.Add("Content-Type", "application/json") req.Header.Add("User-Agent", "GitHub-Hookshot/github") req.Header.Add("X-Github-Event", "push") resp, err := client.Do(req) if err != nil { t.Fatalf("Failed posting webhook: %v", err) } body, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { t.Errorf("Wrong response code, expecting 200, got %s: %s!", resp.Status, string(body)) } // get a list of builds builds, err := osClient.ListBuilds(labels.Everything()) if err != nil { t.Fatalf("Unexpected error: %v", err) } if len(builds.Items) != 1 { t.Fatalf("Expected one build, got %#v", builds) } actual := builds.Items[0] if actual.Status != buildapi.BuildNew { t.Errorf("Expected %s, got %s", buildapi.BuildNew, actual.Status) } if !reflect.DeepEqual(actual.Input, buildConfig.DesiredInput) { t.Errorf("Expected %#v, got %#v", buildConfig.DesiredInput, actual.Input) } }
func (c *config) runApiserver() { minionPort := 10250 osAddr := c.ListenAddr kubePrefix := "/api/v1beta1" osPrefix := "/osapi/v1beta1" kubeClient := c.getKubeClient() osClient := c.getOsClient() etcdClient, etcdServers := c.getEtcdClient() imageRegistry := imageetcd.NewEtcd(etcdClient) // initialize OpenShift API storage := map[string]apiserver.RESTStorage{ "builds": buildregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "buildConfigs": buildconfigregistry.NewStorage(build.NewEtcdRegistry(etcdClient)), "images": image.NewREST(imageRegistry), "imageRepositories": imagerepository.NewREST(imageRegistry), "imageRepositoryMappings": imagerepositorymapping.NewREST(imageRegistry, imageRegistry), "templateConfigs": template.NewStorage(), } osMux := http.NewServeMux() // initialize webhooks whPrefix := osPrefix + "/buildConfigHooks/" osMux.Handle(whPrefix, http.StripPrefix(whPrefix, webhook.NewController(osClient, map[string]webhook.Plugin{ "github": github.New(), }))) // initialize Kubernetes API podInfoGetter := &kubeclient.HTTPPodInfoGetter{ Client: http.DefaultClient, Port: uint(minionPort), } masterConfig := &master.Config{ Client: kubeClient, EtcdServers: etcdServers, HealthCheckMinions: true, Minions: c.nodeHosts, PodInfoGetter: podInfoGetter, } m := master.New(masterConfig) apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(osMux, kubePrefix) apiserver.NewAPIGroup(storage, runtime.Codec).InstallREST(osMux, osPrefix) apiserver.InstallSupport(osMux) osApi := &http.Server{ Addr: osAddr, Handler: apiserver.RecoverPanics(osMux), ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, MaxHeaderBytes: 1 << 20, } go util.Forever(func() { glog.Infof("Started Kubernetes API at http://%s%s", osAddr, kubePrefix) glog.Infof("Started OpenShift API at http://%s%s", osAddr, osPrefix) glog.Fatal(osApi.ListenAndServe()) }, 0) }