Skip to content

Commit

Permalink
Merge pull request #1 from openshift/master-next
Browse files Browse the repository at this point in the history
Update master-next
  • Loading branch information
joshuawilson committed Feb 15, 2019
2 parents dfe28ba + 41171ca commit 331294c
Show file tree
Hide file tree
Showing 35 changed files with 985 additions and 182 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ If the CA bundle of the OpenShift API server is unavailable, fetch the CA certif

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

Expand Down
8 changes: 8 additions & 0 deletions auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ type loginMethod interface {
logout(http.ResponseWriter, *http.Request)
// authenticate fetches the bearer token from the cookie of a request.
authenticate(*http.Request) (*User, error)
// getKubeAdminLogoutURL returns the logout URL for the special
// kube:admin user in OpenShift
getKubeAdminLogoutURL() string
}

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

// GetKubeAdminLogoutURL returns the logout URL for the special kube:admin user in OpenShift
func (a *Authenticator) GetKubeAdminLogoutURL() string {
return a.loginMethod.getKubeAdminLogoutURL()
}

// ExchangeAuthCode allows callers to return a raw token response given a OAuth2
// code. This is useful for clients which need to request refresh tokens.
func (a *Authenticator) ExchangeAuthCode(code string) (idToken, refreshToken string, err error) {
Expand Down
4 changes: 4 additions & 0 deletions auth/auth_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,7 @@ func (o *oidcAuth) authenticate(r *http.Request) (*User, error) {
Token: ls.rawToken,
}, nil
}

func (o *oidcAuth) getKubeAdminLogoutURL() string {
return ""
}
14 changes: 11 additions & 3 deletions auth/auth_openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ import (
"time"

"golang.org/x/oauth2"

"github.com/openshift/console/pkg/proxy"
)

// openShiftAuth implements OpenShift Authentication as defined in:
// https://docs.openshift.com/container-platform/3.9/architecture/additional_concepts/authentication.html
type openShiftAuth struct {
cookiePath string
secureCookies bool
cookiePath string
secureCookies bool
kubeAdminLogoutURL string
}

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

kubeAdminLogoutURL := proxy.SingleJoiningSlash(metadata.Issuer, "/logout")
return oauth2.Endpoint{
AuthURL: metadata.Auth,
TokenURL: metadata.Token,
}, &openShiftAuth{c.cookiePath, c.secureCookies}, nil
}, &openShiftAuth{c.cookiePath, c.secureCookies, kubeAdminLogoutURL}, nil

}

Expand Down Expand Up @@ -157,3 +161,7 @@ func (o *openShiftAuth) authenticate(r *http.Request) (*User, error) {
Token: cookie.Value,
}, nil
}

func (o *openShiftAuth) getKubeAdminLogoutURL() string {
return o.kubeAdminLogoutURL
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ describe(CreateCRDYAML.displayName, () => {
expect(createYAML.props().template).toEqual(safeDump(testResourceInstance));
});

it('handles invalid JSON example object on annotation', () => {
const data = _.cloneDeep(testClusterServiceVersion);
data.metadata.annotations = {'alm-examples': 'invalid === true'};
wrapper = wrapper.setProps({ClusterServiceVersion: {loaded: true, data}} as any);

const createYAML = wrapper.find(Firehose).childAt(0).dive<CreateYAMLProps, {}>();

expect(createYAML.props().template).toEqual(null);
});

it('does not render YAML editor component if ClusterServiceVersion has not loaded yet', () => {
wrapper = wrapper.setProps({ClusterServiceVersion: {loaded: false}} as any);

Expand Down
1 change: 1 addition & 0 deletions frontend/__tests__/features.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('featureReducer', () => {
[FLAGS.OPERATOR_LIFECYCLE_MANAGER]: true,
[FLAGS.OPERATOR_HUB]: false,
[FLAGS.CLUSTER_API]: false,
[FLAGS.MACHINE_CONFIG]: false,
}));
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ describe('Viewing the operators in Operator Hub', () => {
await catalogPageView.clickFilterCheckbox('Red Hat');
});

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

expect(catalogPageView.catalogTileFor('Dynatrace OneAgent').isDisplayed()).toBe(true);
expect(catalogPageView.catalogTileFor('AMQ Streams').isDisplayed()).toBe(true);

await catalogPageView.filterByKeyword('');
});
Expand Down
18 changes: 18 additions & 0 deletions frontend/public/components/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,22 @@ class App extends React.PureComponent {
this._onNavToggle = this._onNavToggle.bind(this);
this._onNavSelect = this._onNavSelect.bind(this);
this._isDesktop = this._isDesktop.bind(this);
this._onResize = this._onResize.bind(this);
this.previousDesktopState = this._isDesktop();

this.state = {
isNavOpen: this._isDesktop(),
};
}

componentWillMount() {
window.addEventListener('resize', this._onResize);
}

componentWillUnmount() {
window.removeEventListener('resize', this._onResize);
}

componentDidUpdate(prevProps) {
const props = this.props;
// Prevent infinite loop in case React Router decides to destroy & recreate the component (changing key)
Expand Down Expand Up @@ -143,6 +153,14 @@ class App extends React.PureComponent {
}
}

_onResize() {
const isDesktop = this._isDesktop();
if (this.previousDesktopState !== isDesktop) {
this.setState({isNavOpen: isDesktop});
this.previousDesktopState = isDesktop;
}
}

render() {
const { isNavOpen } = this.state;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.cluster-channel-modal__dropdown,
.cluster-update-modal__dropdown {
.btn-dropdown,
.dropdown-menu {
width: 100%;
}
}
53 changes: 17 additions & 36 deletions frontend/public/components/cluster-settings/cluster-operator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,31 @@
import * as React from 'react';
import * as _ from 'lodash-es';

import { K8sResourceKind, K8sResourceKindReference, referenceForModel } from '../../module/k8s';
import { ClusterOperatorModel } from '../../models';
import { ColHead, DetailsPage, List, ListHeader, ListPage } from '../factory';
import {
ColHead,
DetailsPage,
List,
ListHeader,
ListPage,
} from '../factory';
import {
getClusterOperatorStatus,
getStatusAndMessage,
K8sResourceKind,
K8sResourceKindReference,
OperatorStatus,
referenceForModel,
} from '../../module/k8s';
import {
navFactory,
ResourceLink,
ResourceSummary,
SectionHeading,
navFactory,
} from '../utils';

enum OperatorStatus {
Available = 'Available',
Updating = 'Updating',
Failing = 'Failing',
Unknown = 'Unknown',
}

export const clusterOperatorReference: K8sResourceKindReference = referenceForModel(ClusterOperatorModel);

const getStatusAndMessage = (operator: K8sResourceKind) => {
const conditions = _.get(operator, 'status.conditions');
const failing: any = _.find(conditions, { type: 'Failing', status: 'True' });
if (failing) {
return { status: OperatorStatus.Failing, message: failing.message };
}

const progressing: any = _.find(conditions, { type: 'Progressing', status: 'True' });
if (progressing) {
return { status: OperatorStatus.Updating, message: progressing.message };
}

const available: any = _.find(conditions, { type: 'Available', status: 'True' });
if (available) {
return { status: OperatorStatus.Available, message: available.message };
}

return { status: OperatorStatus.Unknown, message: '' };
};

export const getClusterOperatorStatus = (operator: K8sResourceKind) => {
const { status } = getStatusAndMessage(operator);
return status;
};

const getIconClass = (status: OperatorStatus) => {
return {
[OperatorStatus.Available]: 'pficon pficon-ok text-success',
Expand Down Expand Up @@ -81,7 +62,7 @@ const ClusterOperatorRow: React.SFC<ClusterOperatorRowProps> = ({obj}) => {
{message ? _.truncate(message, { length: 256, separator: ' ' }) : '-'}
</div>
<div className="col-md-3 col-sm-3 hidden-xs">
{obj.status.version || <span className="text-muted">Unknown</span>}
{_.get(obj, 'status.version') || <span className="text-muted">Unknown</span>}
</div>
</div>;
};
Expand Down

0 comments on commit 331294c

Please sign in to comment.