Skip to content

Commit 41171ca

Browse files
Merge pull request #1188 from openshift/master
Merge master into master-next
2 parents dfe28ba + 75466b3 commit 41171ca

35 files changed

+985
-182
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ If the CA bundle of the OpenShift API server is unavailable, fetch the CA certif
5454

5555
```
5656
oc get secrets -n default --field-selector type=kubernetes.io/service-account-token -o json | \
57-
jq '.items[0].data."service-ca.crt"' -r | python -m base64 -d > examples/ca.crt
57+
jq '.items[0].data."ca.crt"' -r | python -m base64 -d > examples/ca.crt
5858
# Note: use "openssl base64" because the "base64" tool is different between mac and linux
5959
```
6060

auth/auth.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ type loginMethod interface {
7070
logout(http.ResponseWriter, *http.Request)
7171
// authenticate fetches the bearer token from the cookie of a request.
7272
authenticate(*http.Request) (*User, error)
73+
// getKubeAdminLogoutURL returns the logout URL for the special
74+
// kube:admin user in OpenShift
75+
getKubeAdminLogoutURL() string
7376
}
7477

7578
// AuthSource allows callers to switch between Tectonic and OpenShift login support.
@@ -274,6 +277,11 @@ func (a *Authenticator) LogoutFunc(w http.ResponseWriter, r *http.Request) {
274277
a.loginMethod.logout(w, r)
275278
}
276279

280+
// GetKubeAdminLogoutURL returns the logout URL for the special kube:admin user in OpenShift
281+
func (a *Authenticator) GetKubeAdminLogoutURL() string {
282+
return a.loginMethod.getKubeAdminLogoutURL()
283+
}
284+
277285
// ExchangeAuthCode allows callers to return a raw token response given a OAuth2
278286
// code. This is useful for clients which need to request refresh tokens.
279287
func (a *Authenticator) ExchangeAuthCode(code string) (idToken, refreshToken string, err error) {

auth/auth_oidc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,7 @@ func (o *oidcAuth) authenticate(r *http.Request) (*User, error) {
131131
Token: ls.rawToken,
132132
}, nil
133133
}
134+
135+
func (o *oidcAuth) getKubeAdminLogoutURL() string {
136+
return ""
137+
}

auth/auth_openshift.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ import (
1010
"time"
1111

1212
"golang.org/x/oauth2"
13+
14+
"github.com/openshift/console/pkg/proxy"
1315
)
1416

1517
// openShiftAuth implements OpenShift Authentication as defined in:
1618
// https://docs.openshift.com/container-platform/3.9/architecture/additional_concepts/authentication.html
1719
type openShiftAuth struct {
18-
cookiePath string
19-
secureCookies bool
20+
cookiePath string
21+
secureCookies bool
22+
kubeAdminLogoutURL string
2023
}
2124

2225
type openShiftConfig struct {
@@ -83,10 +86,11 @@ func newOpenShiftAuth(ctx context.Context, c *openShiftConfig) (oauth2.Endpoint,
8386
return oauth2.Endpoint{}, nil, err
8487
}
8588

89+
kubeAdminLogoutURL := proxy.SingleJoiningSlash(metadata.Issuer, "/logout")
8690
return oauth2.Endpoint{
8791
AuthURL: metadata.Auth,
8892
TokenURL: metadata.Token,
89-
}, &openShiftAuth{c.cookiePath, c.secureCookies}, nil
93+
}, &openShiftAuth{c.cookiePath, c.secureCookies, kubeAdminLogoutURL}, nil
9094

9195
}
9296

@@ -157,3 +161,7 @@ func (o *openShiftAuth) authenticate(r *http.Request) (*User, error) {
157161
Token: cookie.Value,
158162
}, nil
159163
}
164+
165+
func (o *openShiftAuth) getKubeAdminLogoutURL() string {
166+
return o.kubeAdminLogoutURL
167+
}

frontend/__tests__/components/operator-lifecycle-manager/create-crd-yaml.spec.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ describe(CreateCRDYAML.displayName, () => {
4141
expect(createYAML.props().template).toEqual(safeDump(testResourceInstance));
4242
});
4343

44+
it('handles invalid JSON example object on annotation', () => {
45+
const data = _.cloneDeep(testClusterServiceVersion);
46+
data.metadata.annotations = {'alm-examples': 'invalid === true'};
47+
wrapper = wrapper.setProps({ClusterServiceVersion: {loaded: true, data}} as any);
48+
49+
const createYAML = wrapper.find(Firehose).childAt(0).dive<CreateYAMLProps, {}>();
50+
51+
expect(createYAML.props().template).toEqual(null);
52+
});
53+
4454
it('does not render YAML editor component if ClusterServiceVersion has not loaded yet', () => {
4555
wrapper = wrapper.setProps({ClusterServiceVersion: {loaded: false}} as any);
4656

frontend/__tests__/features.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ describe('featureReducer', () => {
4343
[FLAGS.OPERATOR_LIFECYCLE_MANAGER]: true,
4444
[FLAGS.OPERATOR_HUB]: false,
4545
[FLAGS.CLUSTER_API]: false,
46+
[FLAGS.MACHINE_CONFIG]: false,
4647
}));
4748
});
4849
});

frontend/integration-tests/tests/operator-hub/operator-hub.scenario.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ describe('Viewing the operators in Operator Hub', () => {
4444
await catalogPageView.clickFilterCheckbox('Red Hat');
4545
});
4646

47-
it('displays "Dynatrace OneAgent" as an operator when using the filter "dy"', async() => {
48-
await catalogPageView.filterByKeyword('dy');
47+
it('displays "AMQ Streams" as an operator when using the filter "stre"', async() => {
48+
await catalogPageView.filterByKeyword('stre');
4949

50-
expect(catalogPageView.catalogTileFor('Dynatrace OneAgent').isDisplayed()).toBe(true);
50+
expect(catalogPageView.catalogTileFor('AMQ Streams').isDisplayed()).toBe(true);
5151

5252
await catalogPageView.filterByKeyword('');
5353
});

frontend/public/components/app.jsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,22 @@ class App extends React.PureComponent {
104104
this._onNavToggle = this._onNavToggle.bind(this);
105105
this._onNavSelect = this._onNavSelect.bind(this);
106106
this._isDesktop = this._isDesktop.bind(this);
107+
this._onResize = this._onResize.bind(this);
108+
this.previousDesktopState = this._isDesktop();
107109

108110
this.state = {
109111
isNavOpen: this._isDesktop(),
110112
};
111113
}
112114

115+
componentWillMount() {
116+
window.addEventListener('resize', this._onResize);
117+
}
118+
119+
componentWillUnmount() {
120+
window.removeEventListener('resize', this._onResize);
121+
}
122+
113123
componentDidUpdate(prevProps) {
114124
const props = this.props;
115125
// Prevent infinite loop in case React Router decides to destroy & recreate the component (changing key)
@@ -143,6 +153,14 @@ class App extends React.PureComponent {
143153
}
144154
}
145155

156+
_onResize() {
157+
const isDesktop = this._isDesktop();
158+
if (this.previousDesktopState !== isDesktop) {
159+
this.setState({isNavOpen: isDesktop});
160+
this.previousDesktopState = isDesktop;
161+
}
162+
}
163+
146164
render() {
147165
const { isNavOpen } = this.state;
148166

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.cluster-channel-modal__dropdown,
2+
.cluster-update-modal__dropdown {
3+
.btn-dropdown,
4+
.dropdown-menu {
5+
width: 100%;
6+
}
7+
}

frontend/public/components/cluster-settings/cluster-operator.tsx

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,31 @@
22
import * as React from 'react';
33
import * as _ from 'lodash-es';
44

5-
import { K8sResourceKind, K8sResourceKindReference, referenceForModel } from '../../module/k8s';
65
import { ClusterOperatorModel } from '../../models';
7-
import { ColHead, DetailsPage, List, ListHeader, ListPage } from '../factory';
86
import {
7+
ColHead,
8+
DetailsPage,
9+
List,
10+
ListHeader,
11+
ListPage,
12+
} from '../factory';
13+
import {
14+
getClusterOperatorStatus,
15+
getStatusAndMessage,
16+
K8sResourceKind,
17+
K8sResourceKindReference,
18+
OperatorStatus,
19+
referenceForModel,
20+
} from '../../module/k8s';
21+
import {
22+
navFactory,
923
ResourceLink,
1024
ResourceSummary,
1125
SectionHeading,
12-
navFactory,
1326
} from '../utils';
1427

15-
enum OperatorStatus {
16-
Available = 'Available',
17-
Updating = 'Updating',
18-
Failing = 'Failing',
19-
Unknown = 'Unknown',
20-
}
21-
2228
export const clusterOperatorReference: K8sResourceKindReference = referenceForModel(ClusterOperatorModel);
2329

24-
const getStatusAndMessage = (operator: K8sResourceKind) => {
25-
const conditions = _.get(operator, 'status.conditions');
26-
const failing: any = _.find(conditions, { type: 'Failing', status: 'True' });
27-
if (failing) {
28-
return { status: OperatorStatus.Failing, message: failing.message };
29-
}
30-
31-
const progressing: any = _.find(conditions, { type: 'Progressing', status: 'True' });
32-
if (progressing) {
33-
return { status: OperatorStatus.Updating, message: progressing.message };
34-
}
35-
36-
const available: any = _.find(conditions, { type: 'Available', status: 'True' });
37-
if (available) {
38-
return { status: OperatorStatus.Available, message: available.message };
39-
}
40-
41-
return { status: OperatorStatus.Unknown, message: '' };
42-
};
43-
44-
export const getClusterOperatorStatus = (operator: K8sResourceKind) => {
45-
const { status } = getStatusAndMessage(operator);
46-
return status;
47-
};
48-
4930
const getIconClass = (status: OperatorStatus) => {
5031
return {
5132
[OperatorStatus.Available]: 'pficon pficon-ok text-success',
@@ -81,7 +62,7 @@ const ClusterOperatorRow: React.SFC<ClusterOperatorRowProps> = ({obj}) => {
8162
{message ? _.truncate(message, { length: 256, separator: ' ' }) : '-'}
8263
</div>
8364
<div className="col-md-3 col-sm-3 hidden-xs">
84-
{obj.status.version || <span className="text-muted">Unknown</span>}
65+
{_.get(obj, 'status.version') || <span className="text-muted">Unknown</span>}
8566
</div>
8667
</div>;
8768
};

0 commit comments

Comments
 (0)