From 596135064bd4c64fec842b3c25e395d3cfe39da5 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 14 Oct 2020 09:04:19 -0700 Subject: [PATCH 1/3] Improvements to add new host dialog - Allow download of enroll secret, server certificate, and flagfile - Make instructions step-by-step --- .../EnrollSecretTable/EnrollSecretTable.jsx | 27 ++++- .../hosts/AddHostModal/AddHostModal.jsx | 108 +++++++++++++----- .../hosts/AddHostModal/_styles.scss | 16 ++- .../hosts/ManageHostsPage/ManageHostsPage.jsx | 7 +- tools/osquery/kolide.crt | 44 ++++--- tools/osquery/kolide.key | 76 +++++++----- 6 files changed, 204 insertions(+), 74 deletions(-) diff --git a/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx b/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx index 6d84bc20c8e..956b18475fa 100644 --- a/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx +++ b/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import FileSaver from 'file-saver'; import Button from 'components/buttons/Button'; import enrollSecretInterface from 'interfaces/enroll_secret'; @@ -35,6 +36,20 @@ class EnrollSecretRow extends Component { return false; } + onDownloadSecret = (evt) => { + evt.preventDefault(); + + const { secret } = this.props; + + const filename = 'secret.txt'; + const file = new global.window.File([secret], filename); + + FileSaver.saveAs(file); + + return false; + } + + onToggleSecret = (evt) => { evt.preventDefault(); @@ -47,7 +62,7 @@ class EnrollSecretRow extends Component { renderLabel = () => { const { name } = this.props; const { showSecret, copyMessage } = this.state; - const { onCopySecret, onToggleSecret } = this; + const { onCopySecret, onDownloadSecret, onToggleSecret } = this; return ( @@ -61,6 +76,16 @@ class EnrollSecretRow extends Component { > + | + + Download + + | { + evt.preventDefault(); + + const filename = 'flagfile.txt'; + const file = new global.window.File([flagfileContent], filename); + + FileSaver.saveAs(file); + + return false; + }; + return (
-

- Follow the instructions below to add hosts to your Fleet Instance. -

-
+
  1. -

    - - Fleet / Osquery - Install Docs - -

    -
  2. -
  3. -

    Osquery Enroll Secret

    +

    1. Enroll Secret

    - Provide osquery with one of the following active enroll secrets: + Provide an active enroll secret to allow osquery to authenticate with the Fleet server:

  4. -

    Download Server Certificate (Optional)

    +

    2. Server Certificate

    +

    + Provide the TLS certificate used by the Fleet server to enable secure connections from osquery: +

    +

    + Download Certificate +

    +
  5. +
  6. +

    3. Flagfile

    - If you use the native osquery TLS plugins, Osquery requires the - same TLS certificate that Fleet is using in order to - authenticate. You can fetch the certificate below: + If using the enroll secret and server certificate downloaded above, use the generated flagfile. In some configurations, modifications may need to be made:

    -

    - +

    + Download Flagfile +

    +
  7. +
  8. +

    4. Run Osquery

    +

    + Run osquery from the directory containing the above files (may require sudo or Run as Administrator privileges):

    +
    osqueryd --flagfile=flagfile.txt --verbose
diff --git a/frontend/components/hosts/AddHostModal/_styles.scss b/frontend/components/hosts/AddHostModal/_styles.scss index 96c6f7ade74..108c11f706f 100644 --- a/frontend/components/hosts/AddHostModal/_styles.scss +++ b/frontend/components/hosts/AddHostModal/_styles.scss @@ -46,14 +46,14 @@ margin-left: 10px; padding: 20px; box-sizing: border-box; - + h4 { font-size: 16px; font-weight: $bold; line-height: 1.5; letter-spacing: -0.5px; color: rgba(32, 37, 50, 0.66); - margin: 40px 0 0; + margin: 10px 0 0; .kolidecon { margin-left: 5px; @@ -75,6 +75,12 @@ } } + &__documentation-link { + h4 { + margin: 0; + } + } + &__install-steps { margin: 0; padding: 0; @@ -134,4 +140,10 @@ color: $link; } } + + pre, code { + background-color: #f9f9f9; + } + } + diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx index f9a8f6ceae9..a2f6b0858e0 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx @@ -158,7 +158,7 @@ export class ManageHostsPage extends PureComponent { onFetchCertificate = () => { return Kolide.config.loadCertificate() .then((certificate) => { - const filename = `${global.window.location.host}.pem`; + const filename = 'fleet.pem'; const file = new global.window.File([certificate], filename, { type: 'application/x-pem-file' }); FileSaver.saveAs(file); @@ -306,7 +306,7 @@ export class ManageHostsPage extends PureComponent { renderAddHostModal = () => { const { onFetchCertificate, toggleAddHostModal } = this; const { showAddHostModal } = this.state; - const { enrollSecret } = this.props; + const { enrollSecret, config } = this.props; if (!showAddHostModal) { return false; @@ -322,6 +322,7 @@ export class ManageHostsPage extends PureComponent { onFetchCertificate={onFetchCertificate} onReturnToApp={toggleAddHostModal} enrollSecret={enrollSecret} + config={config} /> ); @@ -668,6 +669,7 @@ const mapStateToProps = (state, { location, params }) => { const { errors: labelErrors, loading: loadingLabels } = state.entities.labels; const { loading: loadingHosts } = state.entities.hosts; const enrollSecret = state.app.enrollSecret; + const config = state.app.config; return { selectedFilter, @@ -684,6 +686,7 @@ const mapStateToProps = (state, { location, params }) => { selectedLabel, selectedOsqueryTable, statusLabels, + config, }; }; diff --git a/tools/osquery/kolide.crt b/tools/osquery/kolide.crt index f617219e2bd..f0cf3219815 100644 --- a/tools/osquery/kolide.crt +++ b/tools/osquery/kolide.crt @@ -1,19 +1,29 @@ -----BEGIN CERTIFICATE----- -MIIDBjCCAe4CCQDjM7ghDw9OgDANBgkqhkiG9w0BAQsFADBFMQ4wDAYDVQQKDAVG -bGVldDEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxHTAbBgNVBAMMFGhvc3QuZG9ja2Vy -LmludGVybmFsMB4XDTE5MDMyNjE5MTQyN1oXDTQ2MDgxMDE5MTQyN1owRTEOMAwG -A1UECgwFRmxlZXQxFDASBgNVBAsMC0RldmVsb3BtZW50MR0wGwYDVQQDDBRob3N0 -LmRvY2tlci5pbnRlcm5hbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AOnDxrXtuB3VpmsExCVXboF0Llcfee4FF4Y0ifS75RjnLSXupZubQWHenBGmQ7qb -3eTBuw59HiTBkB5CZb79FpFyYrxMpXn+7dVJt2N9NnpKkVidqFXaVqTS9P84JQtt -LIPzyQlRFM482Y0RVfY1UnrWUTqze/wUpJP6xY+aPseIbnYvbsGtZ8PjrLMN+6z8 -f2Ef8Hr6uIR2mQe+qu43HuEkjbTnRi1ORj2fr4cSgoVd7FMhIy1yGEaUP4aerB3X -k1h4eOJa/Vd2eE3b3vXg7awAtdPJDWz4LjQCkgzeI5tej+TooAHM0gyun7EPSy+9 -2fgkAkEvY/dco6h+D0ULuNECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAEhGq1t5G -ZyhXEYJrd92HHi6zyRQNlAoQ55utmE/tlNAq1e2k1uEKEeOmIFvaLpQ3ky2z1Aok -Qrn4+TYFcNN6vB99QxNVb3+hDm+hyKj0N7VvvYIX8ms/AUKZUaUahxM4gXDNky35 -l33IYgGmdcSzBiTkTCGABmtHwJ/QAPI1v6iWGXLQ42HNfCCflFHt5AtOs7Nfv0u5 -JsgkMVu+Vj9sOcdE+UtAJ/NQyV+kWFgzUtxdX8QX/NQVFqlNPVV4cRi8KMbBM1q+ -xN2o1vC27vM+5VWTr5sddU6MVJJXIIP4wfe+qbCnD8GE5+7j8XiUrOMsauiafaW2 -cdSv0nZ/WcEovw== +MIIE5jCCAs6gAwIBAgIJAKq0+FAVArUhMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV +BAMMCkZsZWV0IFRlc3QwHhcNMjAxMDE1MTg1ODE5WhcNMzAwNzE1MTg1ODE5WjAV +MRMwEQYDVQQDDApGbGVldCBUZXN0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAttQ62lpMq48/XjQFxYg47D2fgKgTBMjDNSfCt9VpqE3xPnybmWo8VZtk +jmrFM50IhagyYSjvl9iqdrnsl3ZV8KYbWEy6849zDYF1SudmC7/pJyH7QvpKgL7V +4McM62jM905hyFy9KZTAlFiaeezWSWJre7kHsK2u5tsqS6ElatEZmF59sInixaRw +RqVxOhtDm7Sl1c5xKWM6phWoJfykspFpu5J6N2jRQXCfzBYoQWN76OohGouit/BQ +C1xvm+f7wgGZgbbfDjUoHAe9Yhd3XzZsYTgMDt/SRJRDnxFZwo8BAkY9yJm7f3dQ +AEhgJ66KbyoxITdgma1hgmeWibZY4hVymcRxB1B3RNN2at19RNy2J+brMxlG0KZk +nD77EqidrwLAlYcdeU3yLjt0vYPxT+RW7l1jiZlVi/oaykAmVfOhWnTnTwbsYs7O +UMyMyYHQECEs98ex7wrjThIBJScqhsSN1ipAxr5RgaDr+U5IR+tLhMewBy8So+nf +2YuMhLfkCgoY80ELhz5F8avts5hksB0hqnNYr+Nlwm6eXqEPZSzFJmdc1IbmWzq2 +7UH1OQmBFF2qr2j/8dcM+oPNgjrEEQjtyW0S4j2PhjSEbINgcwu0AaABssLI80Vm +Gp1TjUGA92rMwIjlAtcUUB5FOKSS8vAXb1VcDWMkybh9sHj4Z0ECAwEAAaM5MDcw +NQYDVR0RBC4wLIIJbG9jYWxob3N0ghRob3N0LmRvY2tlci5pbnRlcm5hbIIJMTI3 +LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4ICAQBZOY++LNRTVG8XlQGVlOloEKA2WY3P +gXKJLSM7xWSxj2co0v+noyhoInHT7ysub8en59Et+vN53/0OobxNIdEKDUdqs38R +F++Oy6s/MhFHSo87F06t+W91/60ub4iFRHfev1qeNFV6Yzv9sFJ5LpXLFk+qVDb8 +pPyFFE1bXjctDPjD5gUj+Y34XikVKzMb7xddWCNs34v1KCaCBW7kkfefxiZiDR6g +lCEkDzp6xaLS898oCbfFakjr4bvOgBP1IqXLIDLPMhivaxNAooHTtu/3ezp7puix +TSDkjlkStDtEFw/wjyaMcEkk51Gs1ponBbADLRxQ50AHDWk/4vy8GcIVc6CdVEOA +Zw12FN06C4Jviiiv6uCXZ6iZ+V+pjGiGmSNYF+kruUs8BfrJIB89lqxpdQ4Kx01j +AuSFvjRRvIPmvApSdKEjLcY3AYRivXsB/hASMBbjh/p1f/JzSJdxoqSvONhNQJuh ++wcdNVQhGAv3kkLn/HMHTBl2Ur+9tQaJrnR1tWl1IzwLRJIi0Soyp/q5ZjQyFglj +32xW83DZhtpQ2SI1QGy4AvWIPnGHZhMfav02KnKRhZdOMW4oekXRMrwiyXCqIazc +xXzAlCq8dHdP2Y9uvfFxVFyE+uSfkcPxX+DG/ZnpgCS27oKA/qLCybJamlqtveNs +RSjNe5qwGi0ifA== -----END CERTIFICATE----- diff --git a/tools/osquery/kolide.key b/tools/osquery/kolide.key index e5024c873cf..f8ac67b1e56 100644 --- a/tools/osquery/kolide.key +++ b/tools/osquery/kolide.key @@ -1,28 +1,52 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDpw8a17bgd1aZr -BMQlV26BdC5XH3nuBReGNIn0u+UY5y0l7qWbm0Fh3pwRpkO6m93kwbsOfR4kwZAe -QmW+/RaRcmK8TKV5/u3VSbdjfTZ6SpFYnahV2lak0vT/OCULbSyD88kJURTOPNmN -EVX2NVJ61lE6s3v8FKST+sWPmj7HiG52L27BrWfD46yzDfus/H9hH/B6+riEdpkH -vqruNx7hJI2050YtTkY9n6+HEoKFXexTISMtchhGlD+Gnqwd15NYeHjiWv1XdnhN -29714O2sALXTyQ1s+C40ApIM3iObXo/k6KABzNIMrp+xD0svvdn4JAJBL2P3XKOo -fg9FC7jRAgMBAAECggEAPPViohqFgrIuHYY2qA4usO9dDjcVEq6dPdABkaJV0bKn -IVckNHm+CQmF5UxYKRdwO7ERWGvkKm2XaWyjH7Tb573OZZAPLsr9tjrs6bLDPAyp -7lPei9TN91lTriIz9tDXZOlzqUxNgqJ3kMPOiM/K3GF6+TXIxSmU6UnhrtroOBuq -K+o/qC5K8CnqpBhBQt6qtn/YdfbcABogRbwojnHRl068nMV9kJLp7/I5hgI8Vr+v -xMXI87wbL7kglcBZweG2EL//C31eSEVG2cW+0cIefQil0ZIPWgX0z5Oex2OD+cLL -E+FIp/waZ7plCiikNNMo+gm/4uy9iupxg+z5W71NyQKBgQD2OSTe8w2Ns9zzLIXC -5ZrFTa5LmTJ8bIv7/5kCS7fSGnoDPZvaRfnqzVEoCUp5D2N09NOJIsoNGrIGnMCc -q6HwGEzGwmOgtzYu1r2jC+6jlcJW4tMr8k52CRO3y3LvsYkmt6tYIBgMVoxIupce -QyBm5zVccyIvdhYhapgcSTJrtwKBgQDzC/30lTlBWsLiqLtfHAwM3YJgdVczJrbe -WDieUd8ywTVupDOhBSGwVGmXGLQE5G/eNfwlsBq2iij7H/WdkX6mD1YmnQJUit3x -0cPmDwWMo3vGLUUUI34WJ/2WSxdTtfaIcaFlV6S9Bp9B5K208kG/cZliqBWG1mtS -a/AdsdcPtwKBgFHan2pKzNet0qc4xuMK54/uCiJxtHnur/6/cwNzXpHHYYaQRa6j -kri/NtqjdBGYzwyDk4tEeH0wwbw3AkVTPYuO2H8/AlXccnPRyctZXSUe1TODRoaW -kATncZmpVfVfROQNLTYnvTbk0tAez7wsvqnW9UNdtyCmFidXw2er4cozAoGADuPK -MCTAODfGPrqVmBMQzez4Is6tg+24QFDpTxG2+dYKXvfiTdgRo0rYmTAjPzV7gQKP -qwNp74rxTck8c+XI+4VvAriVvvYu+LSgKsT60w3k9FQrqjsua08R4xZAnJlGPD+x -4pKG/imcsh2/YpmA26iq+/dOMk+KjacdM8SEZ2sCgYB/qypw7LpskkGA5ITODv5A -cAHVCCDMGNJiR4XpdOwHNAcd6EWjB/366/MwKfV24KnZH0RZe+pU2e4dP8miHNN0 -dFOpAokCD3Eh7LGDVM6bYkQabG3XTmN8g9a4V2e63n5Bl2HZx0Qp1bHEtqsOujpj -5G5maHPlTRoNlvk4BiEZDA== +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 +mWZen+G8ANnds10V7TmcpoaPSSoJMF0= -----END PRIVATE KEY----- From ef95d77d9ef7e03f180119fd4029b70424bf1f23 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Mon, 19 Oct 2020 10:32:00 -0700 Subject: [PATCH 2/3] Improved error handling for certificate fetch --- .../hosts/AddHostModal/AddHostModal.jsx | 39 ++++++++++++++++--- .../hosts/AddHostModal/_styles.scss | 4 ++ .../hosts/ManageHostsPage/ManageHostsPage.jsx | 15 +------ 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/frontend/components/hosts/AddHostModal/AddHostModal.jsx b/frontend/components/hosts/AddHostModal/AddHostModal.jsx index 266bc1797a4..319bed723db 100644 --- a/frontend/components/hosts/AddHostModal/AddHostModal.jsx +++ b/frontend/components/hosts/AddHostModal/AddHostModal.jsx @@ -2,34 +2,60 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import FileSaver from 'file-saver'; +import Kolide from 'kolide'; import Button from 'components/buttons/Button'; import configInterface from 'interfaces/config'; import enrollSecretInterface from 'interfaces/enroll_secret'; import EnrollSecretTable from 'components/config/EnrollSecretTable'; import Icon from 'components/icons/Icon'; -import certificate from '../../../../assets/images/osquery-certificate.svg'; const baseClass = 'add-host-modal'; class AddHostModal extends Component { static propTypes = { - onFetchCertificate: PropTypes.func, onReturnToApp: PropTypes.func, enrollSecret: enrollSecretInterface, config: configInterface, }; + constructor(props) { + super(props); + this.state = { fetchCertificateError: undefined }; + } + + componentDidMount() { + Kolide.config.loadCertificate() + .then((certificate) => { + this.setState({ certificate }); + }) + .catch(() => { + this.setState({ fetchCertificateError: 'Failed to load certificate. Is Fleet App URL configured properly?' }); + }); + } + + onFetchCertificate = (evt) => { + evt.preventDefault(); + + const { certificate } = this.state; + + const filename = 'fleet.pem'; + const file = new global.window.File([certificate], filename, { type: 'application/x-pem-file' }); + FileSaver.saveAs(file); + return false; + } + render() { const { config, - onFetchCertificate, onReturnToApp, enrollSecret, } = this.props; + const { fetchCertificateError } = this.state; + let tlsHostname = config.kolide_server_url; try { const serverUrl = new URL(config.kolide_server_url); @@ -42,7 +68,7 @@ class AddHostModal extends Component { throw e; } } - + const flagfileContent = `--enroll_secret_path=secret.txt --tls_server_certs=fleet.pem --tls_hostname=${tlsHostname} @@ -102,7 +128,10 @@ class AddHostModal extends Component { Provide the TLS certificate used by the Fleet server to enable secure connections from osquery:

- Download Certificate + { fetchCertificateError + ? {fetchCertificateError} + : Download Certificate + }

  • diff --git a/frontend/components/hosts/AddHostModal/_styles.scss b/frontend/components/hosts/AddHostModal/_styles.scss index 108c11f706f..b17f009bd3b 100644 --- a/frontend/components/hosts/AddHostModal/_styles.scss +++ b/frontend/components/hosts/AddHostModal/_styles.scss @@ -145,5 +145,9 @@ background-color: #f9f9f9; } + &__error { + color: $alert; + } + } diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx index a2f6b0858e0..f373b6fb82a 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx @@ -155,18 +155,6 @@ export class ManageHostsPage extends PureComponent { .catch(() => false); } - onFetchCertificate = () => { - return Kolide.config.loadCertificate() - .then((certificate) => { - const filename = 'fleet.pem'; - const file = new global.window.File([certificate], filename, { type: 'application/x-pem-file' }); - - FileSaver.saveAs(file); - - return false; - }); - } - onLabelClick = (selectedLabel) => { return (evt) => { evt.preventDefault(); @@ -304,7 +292,7 @@ export class ManageHostsPage extends PureComponent { } renderAddHostModal = () => { - const { onFetchCertificate, toggleAddHostModal } = this; + const { toggleAddHostModal } = this; const { showAddHostModal } = this.state; const { enrollSecret, config } = this.props; @@ -319,7 +307,6 @@ export class ManageHostsPage extends PureComponent { className={`${baseClass}__invite-modal`} > Date: Mon, 19 Oct 2020 10:35:30 -0700 Subject: [PATCH 3/3] Fix lint and tests --- .../config/EnrollSecretTable/EnrollSecretTable.jsx | 6 +++--- .../components/hosts/AddHostModal/AddHostModal.jsx | 12 ++++++------ .../pages/hosts/ManageHostsPage/ManageHostsPage.jsx | 4 ++-- .../hosts/ManageHostsPage/ManageHostsPage.tests.jsx | 3 ++- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx b/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx index 956b18475fa..7adc814938b 100644 --- a/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx +++ b/frontend/components/config/EnrollSecretTable/EnrollSecretTable.jsx @@ -43,13 +43,13 @@ class EnrollSecretRow extends Component { const filename = 'secret.txt'; const file = new global.window.File([secret], filename); - + FileSaver.saveAs(file); return false; } - + onToggleSecret = (evt) => { evt.preventDefault(); @@ -78,7 +78,7 @@ class EnrollSecretRow extends Component { |
    @@ -137,7 +137,7 @@ class AddHostModal extends Component {
  • 3. Flagfile

    - If using the enroll secret and server certificate downloaded above, use the generated flagfile. In some configurations, modifications may need to be made: + If using the enroll secret and server certificate downloaded above, use the generated flagfile. In some configurations, modifications may need to be made:

    Download Flagfile diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx index f373b6fb82a..8aa2ba9dc6a 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx @@ -2,14 +2,13 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import AceEditor from 'react-ace'; import { connect } from 'react-redux'; -import FileSaver from 'file-saver'; import { push } from 'react-router-redux'; import { sortBy } from 'lodash'; import classNames from 'classnames'; -import Kolide from 'kolide'; import AddHostModal from 'components/hosts/AddHostModal'; import Button from 'components/buttons/Button'; +import configInterface from 'interfaces/config'; import HostContainer from 'components/hosts/HostContainer'; import HostPagination from 'components/hosts/HostPagination'; import HostSidePanel from 'components/side_panels/HostSidePanel'; @@ -45,6 +44,7 @@ const baseClass = 'manage-hosts'; export class ManageHostsPage extends PureComponent { static propTypes = { + config: configInterface, dispatch: PropTypes.func, display: PropTypes.oneOf(['Grid', 'List']), hosts: PropTypes.arrayOf(hostInterface), diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx index 23322ee0759..c16e19ca9c6 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tests.jsx @@ -7,7 +7,7 @@ import hostActions from 'redux/nodes/entities/hosts/actions'; import labelActions from 'redux/nodes/entities/labels/actions'; import ConnectedManageHostsPage, { ManageHostsPage } from 'pages/hosts/ManageHostsPage/ManageHostsPage'; import { connectedComponent, createAceSpy, reduxMockStore, stubbedOsqueryTable } from 'test/helpers'; -import { hostStub } from 'test/stubs'; +import { hostStub, configStub } from 'test/stubs'; import * as manageHostsPageActions from 'redux/nodes/components/ManageHostsPage/actions'; const allHostsLabel = { id: 1, display_text: 'All Hosts', slug: 'all-hosts', type: 'all', count: 22 }; @@ -49,6 +49,7 @@ const mockStore = reduxMockStore({ describe('ManageHostsPage - component', () => { const props = { + config: configStub, dispatch: noop, hosts: [], labels: [],