Skip to content

Commit 2e67298

Browse files
Merge pull request #16205 from logonoff/OCPBUGS-80939-robot
OCPBUGS-80939: Add robots.txt policy to console
2 parents 0554368 + 930da3d commit 2e67298

File tree

4 files changed

+51
-25
lines changed

4 files changed

+51
-25
lines changed

frontend/public/robots.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
User-agent: *
2+
Disallow: /

frontend/webpack.config.ts

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin
33
import * as HtmlWebpackPlugin from 'html-webpack-plugin';
44
import * as _ from 'lodash';
55
import * as MiniCssExtractPlugin from 'mini-css-extract-plugin';
6+
import * as CopyWebpackPlugin from 'copy-webpack-plugin';
67
import * as path from 'path';
78
import * as webpack from 'webpack';
89
import { WebpackSharedObject, WebpackSharedConfig } from '@openshift/dynamic-plugin-sdk-webpack';
@@ -24,7 +25,6 @@ interface Configuration extends webpack.Configuration {
2425
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
2526
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
2627
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
27-
const CopyWebpackPlugin = require('copy-webpack-plugin');
2828
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
2929

3030
const NODE_ENV = process.env.NODE_ENV || 'development';
@@ -287,31 +287,16 @@ const config: Configuration = {
287287
}),
288288
new CopyWebpackPlugin({
289289
patterns: [
290-
{ from: path.resolve(__dirname, './public/locales'), to: 'locales' },
291-
{ from: path.resolve(__dirname, './packages/console-shared/locales'), to: 'locales' },
292-
{ from: path.resolve(__dirname, './packages/console-app/locales'), to: 'locales' },
290+
{ from: path.resolve(__dirname, './public/robots.txt'), to: 'robots.txt' },
293291
{
294-
from: path.resolve(__dirname, './packages/operator-lifecycle-manager/locales'),
295-
to: 'locales',
296-
},
297-
{
298-
from: path.resolve(__dirname, './packages/operator-lifecycle-manager-v1/locales'),
299-
to: 'locales',
300-
},
301-
{ from: path.resolve(__dirname, './packages/dev-console/locales'), to: 'locales' },
302-
{ from: path.resolve(__dirname, './packages/knative-plugin/locales'), to: 'locales' },
303-
{ from: path.resolve(__dirname, './packages/container-security/locales'), to: 'locales' },
304-
{ from: path.resolve(__dirname, './packages/shipwright-plugin/locales'), to: 'locales' },
305-
{ from: path.resolve(__dirname, './packages/webterminal-plugin/locales'), to: 'locales' },
306-
{ from: path.resolve(__dirname, './packages/topology/locales'), to: 'locales' },
307-
{ from: path.resolve(__dirname, './packages/helm-plugin/locales'), to: 'locales' },
308-
{ from: path.resolve(__dirname, './packages/git-service/locales'), to: 'locales' },
309-
{ from: path.resolve(__dirname, './packages/metal3-plugin/locales'), to: 'locales' },
310-
{ from: path.resolve(__dirname, './packages/vsphere-plugin/locales'), to: 'locales' },
311-
{ from: path.resolve(__dirname, './packages/insights-plugin/locales'), to: 'locales' },
312-
{
313-
from: path.resolve(__dirname, './packages/console-telemetry-plugin/locales'),
314-
to: 'locales',
292+
from: './{packages/*,public}/locales',
293+
// Flat locales directory structure: /static/locales/{en,fr,...}/{namespace}.json
294+
to: ({ absoluteFilename }) => {
295+
const segments = absoluteFilename.split(path.sep);
296+
return segments.slice(segments.lastIndexOf('locales')).join(path.sep);
297+
},
298+
context: path.resolve(__dirname),
299+
filter: (p) => path.extname(p) === '.json',
315300
},
316301
],
317302
}),

pkg/server/robots_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package server
2+
3+
import (
4+
"net/http"
5+
"net/http/httptest"
6+
"os"
7+
"path"
8+
"testing"
9+
)
10+
11+
func TestRobotsTxtHandler(t *testing.T) {
12+
dir := t.TempDir()
13+
content := "User-agent: *\nDisallow: /\n"
14+
if err := os.WriteFile(path.Join(dir, "robots.txt"), []byte(content), 0644); err != nil {
15+
t.Fatal(err)
16+
}
17+
18+
mux := http.NewServeMux()
19+
mux.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
20+
http.ServeFile(w, r, path.Join(dir, "robots.txt"))
21+
})
22+
23+
req := httptest.NewRequest(http.MethodGet, "/robots.txt", nil)
24+
rec := httptest.NewRecorder()
25+
mux.ServeHTTP(rec, req)
26+
27+
if rec.Code != http.StatusOK {
28+
t.Errorf("expected status 200, got %d", rec.Code)
29+
}
30+
if got := rec.Body.String(); got != content {
31+
t.Errorf("expected body %q, got %q", content, got)
32+
}
33+
}

pkg/server/server.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,12 @@ func (s *Server) HTTPHandler() (http.Handler, error) {
335335
staticHandler := http.StripPrefix(proxy.SingleJoiningSlash(s.BaseURL.Path, "/static/"), disableDirectoryListing(http.FileServer(http.Dir(s.PublicDir))))
336336
handle("/static/", middleware.WithGZIPEncoding(middleware.WithSecurityHeaders(staticHandler)))
337337

338+
// Register robots.txt at the origin root so crawlers can find it at /robots.txt
339+
// regardless of s.BaseURL.Path (e.g., /console/).
340+
mux.Handle("/robots.txt", middleware.WithSecurityHeaders(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
341+
http.ServeFile(w, r, path.Join(s.PublicDir, "robots.txt"))
342+
})))
343+
338344
if s.CustomLogoFiles != nil {
339345
handleFunc(customLogoEndpoint, func(w http.ResponseWriter, r *http.Request) {
340346
serverconfig.CustomLogosHandler(w, r, s.CustomLogoFiles, s.CustomFaviconFiles)

0 commit comments

Comments
 (0)