diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c450d949..a8e471e8 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -56,10 +56,40 @@ jobs: echo "::add-mask::$ROX_PASSWORD" echo "ROX_PASSWORD=$ROX_PASSWORD" >> $GITHUB_ENV - name: Wait for scanner to start - run: sleep 120 + run: kubectl wait --for=condition=ready --timeout=360s pod -l app=scanner -n stackrox - name: Add stackrox certificate run: scripts/set-certificates.sh - name: Run tests env: ROX_ENDPOINT: 'https://central.stackrox:8000' run: make -C functionaltest-jenkins-plugin test + + - name: Collect Kubernetes logs + if: always() + run: | + mkdir -p k8s-logs + echo "=== Collecting pod logs ===" + kubectl get pods -A -o wide > k8s-logs/pods.txt || true + kubectl get events -A --sort-by='.lastTimestamp' > k8s-logs/events.txt || true + + echo "=== Collecting StackRox logs ===" + for pod in $(kubectl get pods -n stackrox -o name 2>/dev/null || true); do + name=$(echo $pod | sed 's/pod\///') + kubectl logs -n stackrox $pod --all-containers --timestamps > k8s-logs/${name}.log 2>&1 || true + done + + echo "=== Collecting describe output ===" + kubectl describe pods -n stackrox > k8s-logs/pods-describe.txt || true + kubectl describe deployments -n stackrox > k8s-logs/deployments-describe.txt || true + + echo "=== Collecting configmaps and secrets ===" + kubectl get configmaps -n stackrox -o yaml > k8s-logs/configmaps.yaml || true + kubectl get secrets -n stackrox -o yaml > k8s-logs/secrets.yaml || true + + - name: Upload Kubernetes logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: kubernetes-logs + path: k8s-logs/ + retention-days: 7 diff --git a/functionaltest-jenkins-plugin/build.gradle b/functionaltest-jenkins-plugin/build.gradle index 66504690..49ffd918 100644 --- a/functionaltest-jenkins-plugin/build.gradle +++ b/functionaltest-jenkins-plugin/build.gradle @@ -29,7 +29,7 @@ repositories { } dependencies { - implementation 'org.jenkins-ci.plugins:stackrox-container-image-scanner:1.4.4' + implementation files('../stackrox-container-image-scanner/target/classes') implementation 'org.codehaus.groovy:groovy-all:3.0.8' implementation 'org.spockframework:spock-core:2.0-groovy-3.0' implementation 'com.offbytwo.jenkins:jenkins-client:0.3.8' diff --git a/functionaltest-jenkins-plugin/src/main/groovy/RestApiClient.groovy b/functionaltest-jenkins-plugin/src/main/groovy/RestApiClient.groovy index c7e8b1df..31189d9b 100644 --- a/functionaltest-jenkins-plugin/src/main/groovy/RestApiClient.groovy +++ b/functionaltest-jenkins-plugin/src/main/groovy/RestApiClient.groovy @@ -2,11 +2,13 @@ import java.time.Duration import groovy.transform.CompileStatic import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import com.stackrox.api.ApiTokenServiceApi import com.stackrox.api.MetadataServiceApi import com.stackrox.api.PolicyServiceApi import com.stackrox.invoker.ApiClient +import com.stackrox.model.PolicyServicePutPolicyBody import com.stackrox.model.StorageListPolicy import com.stackrox.model.StoragePolicy import com.stackrox.model.V1GenerateTokenRequest @@ -23,7 +25,16 @@ class RestApiClient { ApiTokenServiceApi tokenApi RestApiClient() { + HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { + @Override + void log(String message) { + println("[HTTP] ${message}") + } + }) + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY) + OkHttpClient client = OkHttpClient.Builder.newInstance() + .addInterceptor(loggingInterceptor) .retryOnConnectionFailure(true) .connectTimeout(TIMEOUT) .readTimeout(TIMEOUT) @@ -50,11 +61,39 @@ class RestApiClient { } List getPolicies() { - return policyServiceApi.policyServiceListPolicies(null, null, null, null, null).getPolicies() + return policyServiceApi.policyServiceListPolicies(null, null, null, null, null, null, null).getPolicies() } void updatePolicy(StoragePolicy policyObj, String id) { - policyServiceApi.policyServicePutPolicy(id, policyObj) + // Convert StoragePolicy to PolicyServicePutPolicyBody for openapi-generator 7.25.0 + PolicyServicePutPolicyBody body = new PolicyServicePutPolicyBody() + body.with { + setName(policyObj.getName()) + setDescription(policyObj.getDescription()) + setRationale(policyObj.getRationale()) + setRemediation(policyObj.getRemediation()) + setDisabled(policyObj.getDisabled()) + setCategories(policyObj.getCategories()) + setLifecycleStages(policyObj.getLifecycleStages()) + setEventSource(policyObj.getEventSource()) + setExclusions(policyObj.getExclusions()) + setScope(policyObj.getScope()) + setSeverity(policyObj.getSeverity()) + setEnforcementActions(policyObj.getEnforcementActions()) + setNotifiers(policyObj.getNotifiers()) + setSoRTName(policyObj.getSoRTName()) + setSoRTLifecycleStage(policyObj.getSoRTLifecycleStage()) + setSoRTEnforcement(policyObj.getSoRTEnforcement()) + setPolicyVersion(policyObj.getPolicyVersion()) + setPolicySections(policyObj.getPolicySections()) + setMitreAttackVectors(policyObj.getMitreAttackVectors()) + setCriteriaLocked(policyObj.getCriteriaLocked()) + setMitreVectorsLocked(policyObj.getMitreVectorsLocked()) + setIsDefault(policyObj.getIsDefault()) + setSource(policyObj.getSource()) + } + + policyServiceApi.policyServicePutPolicy(id, body) } StoragePolicy getPolicy(String id) { diff --git a/functionaltest-jenkins-plugin/src/test/groovy/ImageScanningTest.groovy b/functionaltest-jenkins-plugin/src/test/groovy/ImageScanningTest.groovy index dee0c8c6..00f2c47a 100644 --- a/functionaltest-jenkins-plugin/src/test/groovy/ImageScanningTest.groovy +++ b/functionaltest-jenkins-plugin/src/test/groovy/ImageScanningTest.groovy @@ -7,10 +7,8 @@ import static com.stackrox.model.StorageLifecycleStage.DEPLOY import com.offbytwo.jenkins.model.BuildResult import com.stackrox.model.StorageEnforcementAction -import com.stackrox.model.StorageImageNamePolicy import com.stackrox.model.StorageListPolicy import com.stackrox.model.StoragePolicy -import com.stackrox.model.StoragePolicyFields import util.Config @@ -24,11 +22,11 @@ class ImageScanningTest extends BaseSpecification { @Unroll def "image scanning test with toggle enforcement(#imageName, #policyName, #enforcements, #endStatus)"() { given: - updatePolicy("Fixable CVSS >= 7", "latest", []) - updatePolicy("Fixable Severity at least Important", "latest", []) + updatePolicy("Fixable CVSS >= 7", []) + updatePolicy("Fixable Severity at least Important", []) when: - StoragePolicy enforcementPolicy = updatePolicy(policyName, "latest", enforcements) + StoragePolicy enforcementPolicy = updatePolicy(policyName, enforcements) then: assert enforcementPolicy.enforcementActions == enforcements @@ -52,7 +50,7 @@ class ImageScanningTest extends BaseSpecification { def "image scanning test with images enforcement turned on (#imageName, #policyName, #tag)"() { when: def enforcements = [FAIL_BUILD_ENFORCEMENT] - StoragePolicy enforcementPolicy = updatePolicy(policyName, tag, enforcements) + StoragePolicy enforcementPolicy = updatePolicy(policyName, enforcements) then: assert enforcementPolicy.enforcementActions == enforcements @@ -103,17 +101,19 @@ class ImageScanningTest extends BaseSpecification { .createJobConfig() } - StoragePolicy updatePolicy(String policyName, String tag, List enforcements) { + StoragePolicy updatePolicy(String policyName, List enforcements) { List policies = restApiClient.policies def policyId = policies.find { it.name == policyName }?.id assert policyId != null def policy = restApiClient.getPolicy(policyId) - policy.setEnforcementActions(enforcements) - policy.setFields(new StoragePolicyFields().imageName(new StorageImageNamePolicy().tag(tag))) - policy.setDisabled(false) - // Clear exclusions to avoid serialization issues with null scope values - policy.setExclusions([]) + policy.with { + setEnforcementActions(enforcements) + setDisabled(false) + // Clear exclusions and scope to avoid serialization issues with null values + setExclusions([]) + setScope([]) + } restApiClient.updatePolicy(policy, policyId) return restApiClient.getPolicy(policyId) } diff --git a/stackrox-container-image-scanner/pom.xml b/stackrox-container-image-scanner/pom.xml index 83f552d6..3a782b70 100644 --- a/stackrox-container-image-scanner/pom.xml +++ b/stackrox-container-image-scanner/pom.xml @@ -226,7 +226,7 @@ org.openapitools openapi-generator-maven-plugin - 7.14.0 + 7.25.0 @@ -249,6 +249,9 @@ src/gen/java/main true + + java=javaField +