... | ... |
@@ -501,7 +501,19 @@ function install_router { |
501 | 501 |
echo "[INFO] Installing the router" |
502 | 502 |
echo '{"kind":"ServiceAccount","apiVersion":"v1","metadata":{"name":"router"}}' | oc create -f - --config="${ADMIN_KUBECONFIG}" |
503 | 503 |
oc get scc privileged -o json --config="${ADMIN_KUBECONFIG}" | sed '/\"users\"/a \"system:serviceaccount:default:router\",' | oc replace scc privileged -f - --config="${ADMIN_KUBECONFIG}" |
504 |
- openshift admin router --create --credentials="${MASTER_CONFIG_DIR}/openshift-router.kubeconfig" --config="${ADMIN_KUBECONFIG}" --images="${USE_IMAGES}" --service-account=router |
|
504 |
+ # Create a TLS certificate for the router |
|
505 |
+ if [[ -n "${CREATE_ROUTER_CERT-}" ]]; then |
|
506 |
+ echo "[INFO] Generating router TLS certificate" |
|
507 |
+ oadm ca create-server-cert --signer-cert=${MASTER_CONFIG_DIR}/ca.crt \ |
|
508 |
+ --signer-key=${MASTER_CONFIG_DIR}/ca.key \ |
|
509 |
+ --signer-serial=${MASTER_CONFIG_DIR}/ca.serial.txt \ |
|
510 |
+ --hostnames="*.${API_HOST}.xip.io" \ |
|
511 |
+ --cert=${MASTER_CONFIG_DIR}/router.crt --key=${MASTER_CONFIG_DIR}/router.key |
|
512 |
+ cat ${MASTER_CONFIG_DIR}/router.crt ${MASTER_CONFIG_DIR}/router.key \ |
|
513 |
+ ${MASTER_CONFIG_DIR}/ca.crt > ${MASTER_CONFIG_DIR}/router.pem |
|
514 |
+ ROUTER_DEFAULT_CERT="--default-cert=${MASTER_CONFIG_DIR}/router.pem" |
|
515 |
+ fi |
|
516 |
+ openshift admin router --create --credentials="${MASTER_CONFIG_DIR}/openshift-router.kubeconfig" --config="${ADMIN_KUBECONFIG}" --images="${USE_IMAGES}" --service-account=router ${ROUTER_DEFAULT_CERT-} |
|
505 | 517 |
} |
506 | 518 |
|
507 | 519 |
# install registry for the extended tests |
508 | 520 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,95 @@ |
0 |
+package builds |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "fmt" |
|
4 |
+ "net" |
|
5 |
+ "net/url" |
|
6 |
+ "path/filepath" |
|
7 |
+ |
|
8 |
+ g "github.com/onsi/ginkgo" |
|
9 |
+ o "github.com/onsi/gomega" |
|
10 |
+ |
|
11 |
+ exutil "github.com/openshift/origin/test/extended/util" |
|
12 |
+ testutil "github.com/openshift/origin/test/util" |
|
13 |
+) |
|
14 |
+ |
|
15 |
+// hostname returns the hostname from a hostport specification |
|
16 |
+func hostname(hostport string) (string, error) { |
|
17 |
+ host, _, err := net.SplitHostPort(hostport) |
|
18 |
+ return host, err |
|
19 |
+} |
|
20 |
+ |
|
21 |
+var _ = g.Describe("builds: parallel: gitauth: Check build for private source repository access", func() { |
|
22 |
+ defer g.GinkgoRecover() |
|
23 |
+ |
|
24 |
+ const ( |
|
25 |
+ gitServerDeploymentConfigName = "gitserver" |
|
26 |
+ sourceSecretName = "sourcesecret" |
|
27 |
+ hostNameSuffix = "xip.io" |
|
28 |
+ gitUserName = "gituser" |
|
29 |
+ gitPassword = "gituserpassword" |
|
30 |
+ buildConfigName = "gitauthtest" |
|
31 |
+ sourceURLTemplate = "https://gitserver.%s/ruby-hello-world" |
|
32 |
+ ) |
|
33 |
+ |
|
34 |
+ var ( |
|
35 |
+ gitServerFixture = exutil.FixturePath("fixtures", "test-gitserver.yaml") |
|
36 |
+ testBuildFixture = exutil.FixturePath("fixtures", "test-auth-build.yaml") |
|
37 |
+ oc = exutil.NewCLI("build-sti-env", exutil.KubeConfigPath()) |
|
38 |
+ caCertPath = filepath.Join(filepath.Dir(exutil.KubeConfigPath()), "ca.crt") |
|
39 |
+ ) |
|
40 |
+ |
|
41 |
+ g.JustBeforeEach(func() { |
|
42 |
+ g.By("waiting for builder service account") |
|
43 |
+ err := exutil.WaitForBuilderAccount(oc.KubeREST().ServiceAccounts(oc.Namespace())) |
|
44 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
45 |
+ }) |
|
46 |
+ |
|
47 |
+ g.Describe("Build using a username, password, and CA certificate", func() { |
|
48 |
+ g.It("should create a new build using the internal gitserver", func() { |
|
49 |
+ oc.SetOutputDir(exutil.TestContext.OutputDir) |
|
50 |
+ |
|
51 |
+ g.By("obtaining the configured API server host from config") |
|
52 |
+ adminClientConfig, err := testutil.GetClusterAdminClientConfig(exutil.KubeConfigPath()) |
|
53 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
54 |
+ hostURL, err := url.Parse(adminClientConfig.Host) |
|
55 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
56 |
+ host, err := hostname(hostURL.Host) |
|
57 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
58 |
+ routeSuffix := fmt.Sprintf("%s.%s", host, hostNameSuffix) |
|
59 |
+ |
|
60 |
+ g.By(fmt.Sprintf("calling oc new-app -f %q -p ROUTE_SUFFIX=%s", gitServerFixture, routeSuffix)) |
|
61 |
+ err = oc.Run("new-app").Args("-f", gitServerFixture, "-p", fmt.Sprintf("ROUTE_SUFFIX=%s", routeSuffix)).Execute() |
|
62 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
63 |
+ |
|
64 |
+ g.By("expecting the deployment of the gitserver to be in the Complete phase") |
|
65 |
+ err = exutil.WaitForADeployment(oc.KubeREST().ReplicationControllers(oc.Namespace()), gitServerDeploymentConfigName, |
|
66 |
+ exutil.CheckDeploymentCompletedFunc, exutil.CheckDeploymentFailedFunc) |
|
67 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
68 |
+ |
|
69 |
+ g.By(fmt.Sprintf("creating a new secret for the gitserver by calling oc secrets new-basicauth %s --username=%s --password=%s --cacert=%s", |
|
70 |
+ sourceSecretName, gitUserName, gitPassword, caCertPath)) |
|
71 |
+ err = oc.Run("secrets"). |
|
72 |
+ Args("new-basicauth", sourceSecretName, |
|
73 |
+ fmt.Sprintf("--username=%s", gitUserName), |
|
74 |
+ fmt.Sprintf("--password=%s", gitPassword), |
|
75 |
+ fmt.Sprintf("--ca-cert=%s", caCertPath)).Execute() |
|
76 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
77 |
+ |
|
78 |
+ sourceURL := fmt.Sprintf(sourceURLTemplate, routeSuffix) |
|
79 |
+ g.By(fmt.Sprintf("creating a new BuildConfig by calling oc new-app -f %q -p SOURCE_SECRET=%s,SOURCE_URL=%s", |
|
80 |
+ testBuildFixture, sourceSecretName, sourceURL)) |
|
81 |
+ err = oc.Run("new-app").Args("-f", testBuildFixture, "-p", fmt.Sprintf("SOURCE_SECRET=%s,SOURCE_URL=%s", |
|
82 |
+ sourceSecretName, sourceURL)).Execute() |
|
83 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
84 |
+ |
|
85 |
+ g.By("starting a test build") |
|
86 |
+ buildName, err := oc.Run("start-build").Args(buildConfigName).Output() |
|
87 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
88 |
+ |
|
89 |
+ g.By(fmt.Sprintf("expecting build %s to complete successfully", buildName)) |
|
90 |
+ err = exutil.WaitForABuild(oc.REST().Builds(oc.Namespace()), buildName, exutil.CheckBuildSuccessFunc, exutil.CheckBuildFailedFunc) |
|
91 |
+ o.Expect(err).NotTo(o.HaveOccurred()) |
|
92 |
+ }) |
|
93 |
+ }) |
|
94 |
+}) |
... | ... |
@@ -82,11 +82,18 @@ if [[ -z ${TEST_ONLY+x} ]]; then |
82 | 82 |
|
83 | 83 |
trap "exit" INT TERM |
84 | 84 |
trap "cleanup" EXIT |
85 |
- |
|
86 | 85 |
echo "[INFO] Starting server" |
87 | 86 |
|
88 | 87 |
setup_env_vars |
89 | 88 |
reset_tmp_dir |
89 |
+ # when selinux is enforcing, the volume dir selinux label needs to be |
|
90 |
+ # svirt_sandbox_file_t |
|
91 |
+ # |
|
92 |
+ # TODO: fix the selinux policy to either allow openshift_var_lib_dir_t |
|
93 |
+ # or to default the volume dir to svirt_sandbox_file_t. |
|
94 |
+ if selinuxenabled; then |
|
95 |
+ sudo chcon -t svirt_sandbox_file_t ${VOLUME_DIR} |
|
96 |
+ fi |
|
90 | 97 |
configure_os_server |
91 | 98 |
start_os_server |
92 | 99 |
|
... | ... |
@@ -94,6 +101,7 @@ if [[ -z ${TEST_ONLY+x} ]]; then |
94 | 94 |
|
95 | 95 |
install_registry |
96 | 96 |
wait_for_registry |
97 |
+ CREATE_ROUTER_CERT=1 install_router |
|
97 | 98 |
|
98 | 99 |
echo "[INFO] Creating image streams" |
99 | 100 |
oc create -n openshift -f examples/image-streams/image-streams-centos7.json --config="${ADMIN_KUBECONFIG}" |
100 | 101 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,30 @@ |
0 |
+apiVersion: v1 |
|
1 |
+kind: Template |
|
2 |
+labels: |
|
3 |
+ template: gitserver |
|
4 |
+metadata: |
|
5 |
+ name: gitserver |
|
6 |
+parameters: |
|
7 |
+- name: SOURCE_URL |
|
8 |
+ required: true |
|
9 |
+- name: SOURCE_SECRET |
|
10 |
+ required: true |
|
11 |
+objects: |
|
12 |
+- apiVersion: v1 |
|
13 |
+ kind: BuildConfig |
|
14 |
+ metadata: |
|
15 |
+ name: gitauthtest |
|
16 |
+ spec: |
|
17 |
+ source: |
|
18 |
+ git: |
|
19 |
+ uri: ${SOURCE_URL} |
|
20 |
+ type: Git |
|
21 |
+ sourceSecret: |
|
22 |
+ name: ${SOURCE_SECRET} |
|
23 |
+ strategy: |
|
24 |
+ sourceStrategy: |
|
25 |
+ from: |
|
26 |
+ kind: ImageStreamTag |
|
27 |
+ name: ruby:latest |
|
28 |
+ namespace: openshift |
|
29 |
+ type: Source |
0 | 30 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,183 @@ |
0 |
+apiVersion: v1 |
|
1 |
+kind: Template |
|
2 |
+labels: |
|
3 |
+ template: gitserver |
|
4 |
+metadata: |
|
5 |
+ name: gitserver |
|
6 |
+parameters: |
|
7 |
+- name: ROUTE_SUFFIX |
|
8 |
+ required: true |
|
9 |
+objects: |
|
10 |
+# The gitserver is deployed as a singleton pod and uses a very small amount |
|
11 |
+# of resources. It can host or transiently serve Git repositories, as well |
|
12 |
+# as automatically integrate with builds in a namespace. |
|
13 |
+- apiVersion: v1 |
|
14 |
+ kind: DeploymentConfig |
|
15 |
+ metadata: |
|
16 |
+ name: gitserver |
|
17 |
+ labels: |
|
18 |
+ app: gitserver |
|
19 |
+ spec: |
|
20 |
+ replicas: 1 # the gitserver is not HA and should not be scaled past 1 |
|
21 |
+ selector: |
|
22 |
+ run-container: gitserver |
|
23 |
+ template: |
|
24 |
+ metadata: |
|
25 |
+ labels: |
|
26 |
+ run-container: gitserver |
|
27 |
+ spec: |
|
28 |
+ containers: |
|
29 |
+ - name: gitserver |
|
30 |
+ image: openshift/origin-gitserver |
|
31 |
+ serviceAccountName: gitserver |
|
32 |
+ readinessProbe: |
|
33 |
+ tcpSocket: |
|
34 |
+ port: 8080 |
|
35 |
+ ports: |
|
36 |
+ - containerPort: 8080 |
|
37 |
+ |
|
38 |
+ env: |
|
39 |
+ # Each environment variable matching GIT_INITIAL_CLONE_* will |
|
40 |
+ # be cloned when the process starts; failures will be logged. |
|
41 |
+ # <name> must be [A-Z0-9_\-\.], the cloned directory name will |
|
42 |
+ # be lowercased. If the name is invalid the pod will halt. If |
|
43 |
+ # the repository already exists on disk, it will be updated |
|
44 |
+ # from the remote. |
|
45 |
+ # |
|
46 |
+ - name: GIT_INITIAL_CLONE_1 |
|
47 |
+ value: https://github.com/openshift/ruby-hello-world.git;ruby-hello-world |
|
48 |
+ |
|
49 |
+ |
|
50 |
+ # The namespace of the pod is required for implicit config |
|
51 |
+ # (passing '-' to AUTOLINK_KUBECONFIG or REQUIRE_SERVER_AUTH) |
|
52 |
+ # and can also be used to target a specific namespace. |
|
53 |
+ - name: POD_NAMESPACE |
|
54 |
+ valueFrom: |
|
55 |
+ fieldRef: |
|
56 |
+ fieldPath: metadata.namespace |
|
57 |
+ |
|
58 |
+ # The URL that builds must use to access the Git repositories |
|
59 |
+ # stored in this app. |
|
60 |
+ # TOOD: support HTTPS |
|
61 |
+ - name: PUBLIC_URL |
|
62 |
+ value: http://gitserver.$(POD_NAMESPACE).svc.cluster.local:8080 |
|
63 |
+ # The directory to store Git repositories in. If not backed |
|
64 |
+ # by a persistent volume, repositories will be lost when |
|
65 |
+ # deployments occur. Use INITIAL_GIT_CLONE and AUTOLINK_* |
|
66 |
+ # to remove the need to use a persistent volume. |
|
67 |
+ - name: GIT_HOME |
|
68 |
+ value: /var/lib/git |
|
69 |
+ # The directory to use as the default hook directory for any |
|
70 |
+ # cloned or autolinked directories. |
|
71 |
+ - name: HOOK_PATH |
|
72 |
+ value: /var/lib/git-hooks |
|
73 |
+ |
|
74 |
+ # Authentication and authorization |
|
75 |
+ |
|
76 |
+ # If 'yes', clients may push to the server with git push. |
|
77 |
+ - name: ALLOW_GIT_PUSH |
|
78 |
+ value: "yes" |
|
79 |
+ # If 'yes', clients may set hooks via the API. However, unless |
|
80 |
+ # the Git home is backed by a persistent volume, any deployment |
|
81 |
+ # will result in the hooks being lost. |
|
82 |
+ - name: ALLOW_GIT_HOOKS |
|
83 |
+ value: "yes" |
|
84 |
+ # If 'yes', clients can create new git repositories on demand |
|
85 |
+ # by pushing. If the data on disk is not backed by a persistent |
|
86 |
+ # volume, the Git repo will be deleted if the deployment is |
|
87 |
+ # updated. |
|
88 |
+ - name: ALLOW_LAZY_CREATE |
|
89 |
+ value: "yes" |
|
90 |
+ # If 'yes', clients can pull without being authenticated. |
|
91 |
+ - name: ALLOW_ANON_GIT_PULL |
|
92 |
+ |
|
93 |
+ # Provides the path to a kubeconfig file in the image that |
|
94 |
+ # should be used to authorize against the server. The value |
|
95 |
+ # '-' will use the pod's service account. |
|
96 |
+ # May not be used in combination with REQUIRE_GIT_AUTH |
|
97 |
+ #- name: REQUIRE_SERVER_AUTH |
|
98 |
+ # value: "-" |
|
99 |
+ |
|
100 |
+ # The namespace to check authorization against when |
|
101 |
+ # REQUIRE_SERVICE_AUTH is used. Users must have 'get' on |
|
102 |
+ # 'pods' to pull and 'create' on 'pods' to push. |
|
103 |
+ - name: AUTH_NAMESPACE |
|
104 |
+ value: $(POD_NAMESPACE) |
|
105 |
+ # Require BASIC authentication with a username and password |
|
106 |
+ # to push or pull. |
|
107 |
+ # May not be used in combination with REQUIRE_SERVER_AUTH |
|
108 |
+ - name: REQUIRE_GIT_AUTH |
|
109 |
+ value: gituser:gituserpassword |
|
110 |
+ |
|
111 |
+ # Autolinking: |
|
112 |
+ # |
|
113 |
+ # The gitserver can automatically clone Git repositories |
|
114 |
+ # associated with a build config and replace the URL with |
|
115 |
+ # a link to the repo on PUBLIC_URL. The default post-receive |
|
116 |
+ # hook on the cloned repo will then trigger a build. You |
|
117 |
+ # may customize the hook with AUTOLINK_HOOK (path to hook). |
|
118 |
+ # To autolink, the account the pod runs under must have 'edit' |
|
119 |
+ # on the AUTOLINK_NAMESPACE: |
|
120 |
+ # |
|
121 |
+ # oc policy add-role-to-user \ |
|
122 |
+ # system:serviceaccount:${namespace}:gitserver edit |
|
123 |
+ # |
|
124 |
+ # Links are checked every time the pod starts. |
|
125 |
+ |
|
126 |
+ # The location to read auth configuration from for autolinking. |
|
127 |
+ # If '-', use the service account token to link. The account |
|
128 |
+ # represented by this config must have the edit role on the |
|
129 |
+ # namespace. |
|
130 |
+ #- name: AUTOLINK_KUBECONFIG |
|
131 |
+ # value: "-" |
|
132 |
+ |
|
133 |
+ # The namespace to autolink |
|
134 |
+ #- name: AUTOLINK_NAMESPACE |
|
135 |
+ # value: $(POD_NAMESPACE) |
|
136 |
+ |
|
137 |
+ # The path to a script in the image to use as the default |
|
138 |
+ # post-receive hook - only set during link, so has no effect |
|
139 |
+ # on cloned repositories. See the "hooks" directory in the |
|
140 |
+ # image for examples. |
|
141 |
+ #- name: AUTOLINK_HOOK |
|
142 |
+ |
|
143 |
+ # The master service host is not signed with the service IP |
|
144 |
+ # so we override with the consistent DNS name. Required for |
|
145 |
+ # connections to the server. |
|
146 |
+ - name: KUBERNETES_SERVICE_HOST |
|
147 |
+ value: kubernetes.default |
|
148 |
+ |
|
149 |
+ volumeMounts: |
|
150 |
+ - mountPath: /var/lib/git/ |
|
151 |
+ name: git |
|
152 |
+ volumes: |
|
153 |
+ - name: git |
|
154 |
+ triggers: |
|
155 |
+ - type: ConfigChange |
|
156 |
+ |
|
157 |
+# The gitserver service is required for DNS resolution |
|
158 |
+- apiVersion: v1 |
|
159 |
+ kind: Service |
|
160 |
+ metadata: |
|
161 |
+ name: gitserver |
|
162 |
+ labels: |
|
163 |
+ app: gitserver |
|
164 |
+ spec: |
|
165 |
+ ports: |
|
166 |
+ - port: 8080 |
|
167 |
+ targetPort: 8080 |
|
168 |
+ selector: |
|
169 |
+ run-container: gitserver |
|
170 |
+- apiVersion: v1 |
|
171 |
+ kind: Route |
|
172 |
+ metadata: |
|
173 |
+ name: gitserver |
|
174 |
+ labels: |
|
175 |
+ app: gitserver |
|
176 |
+ spec: |
|
177 |
+ host: gitserver.${ROUTE_SUFFIX} |
|
178 |
+ tls: |
|
179 |
+ termination: edge |
|
180 |
+ to: |
|
181 |
+ kind: Service |
|
182 |
+ name: gitserver |